Merge "Add name to LogBuffer threads" into tm-dev
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index f49cdbf..4710322 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -1777,7 +1777,10 @@
* {@link Build.VERSION_CODES#S}, but starting from Android version
* {@link Build.VERSION_CODES#TIRAMISU}, expedited jobs for the foreground app are
* guaranteed to be started before {@link JobScheduler#schedule(JobInfo)} returns (assuming
- * all requested constraints are satisfied), similar to foreground services.
+ * all requested constraints are satisfied), similar to foreground services. However, this
+ * start guarantee means there is a higher chance of overlapping executions, as noted in
+ * {@link JobService}, so be sure to handle that properly if you intend to reschedule the
+ * job while it's actively running.
*
* @see JobInfo#isExpedited()
*/
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index 1f4ef04..388bbf1 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -107,7 +107,9 @@
/**
* Schedule a job to be executed. Will replace any currently scheduled job with the same
* ID with the new information in the {@link JobInfo}. If a job with the given ID is currently
- * running, it will be stopped.
+ * running, it will be stopped. Note that in some cases, the newly scheduled job may be started
+ * before the previously running job has been fully stopped. See {@link JobService} for
+ * additional details.
*
* <p class="caution"><strong>Note:</strong> Scheduling a job can have a high cost, even if it's
* rescheduling the same job and the job didn't execute, especially on platform versions before
@@ -131,7 +133,7 @@
* job. If a job with the same ID is already scheduled, it will be replaced with the
* new {@link JobInfo}, but any previously enqueued work will remain and be dispatched the
* next time it runs. If a job with the same ID is already running, the new work will be
- * enqueued for it.
+ * enqueued for it without stopping the job.
*
* <p>The work you enqueue is later retrieved through
* {@link JobParameters#dequeueWork() JobParameters.dequeueWork}. Be sure to see there
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java
index e5b0742..7ed4b62 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobService.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java
@@ -31,6 +31,17 @@
* in blocking any future callbacks from the JobManager - specifically
* {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the
* scheduling requirements are no longer being met.</p>
+ *
+ * As a subclass of {@link Service}, there will only be one active instance of any JobService
+ * subclasses, regardless of job ID. This means that if you schedule multiple jobs with different
+ * job IDs but using the same JobService class, that JobService may receive multiple calls to
+ * {@link #onStartJob(JobParameters)} and {@link #onStopJob(JobParameters)}, with each call being
+ * for the separate jobs.
+ *
+ * <p class="note">Note that if you cancel and reschedule an already executing job,
+ * there may be a small period of time where {@link #onStartJob(JobParameters)} has been called for
+ * the newly scheduled job instance before {@link #onStopJob(JobParameters)} has been called or
+ * fully processed for the old job.</p>
*/
public abstract class JobService extends Service {
private static final String TAG = "JobService";
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 c86353c..afe36b5 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -542,6 +542,22 @@
return mRunningJobs.contains(job);
}
+ /**
+ * Returns true if a job that is "similar" to the provided job is currently running.
+ * "Similar" in this context means any job that the {@link JobStore} would consider equivalent
+ * and replace one with the other.
+ */
+ @GuardedBy("mLock")
+ private boolean isSimilarJobRunningLocked(JobStatus job) {
+ for (int i = mRunningJobs.size() - 1; i >= 0; --i) {
+ JobStatus js = mRunningJobs.valueAt(i);
+ if (job.getUid() == js.getUid() && job.getJobId() == js.getJobId()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Return {@code true} if the state was updated. */
@GuardedBy("mLock")
private boolean refreshSystemStateLocked() {
@@ -699,6 +715,21 @@
continue;
}
+ final boolean isTopEj = nextPending.shouldTreatAsExpeditedJob()
+ && nextPending.lastEvaluatedBias == JobInfo.BIAS_TOP_APP;
+ // Avoid overlapping job execution as much as possible.
+ if (!isTopEj && isSimilarJobRunningLocked(nextPending)) {
+ if (DEBUG) {
+ Slog.w(TAG, "Delaying execution of job because of similarly running one: "
+ + nextPending);
+ }
+ // It would be nice to let the JobService running the other similar job know about
+ // this new job so that it doesn't unbind from the JobService and we can call
+ // onStartJob as soon as the older job finishes.
+ // TODO: optimize the job reschedule flow to reduce service binding churn
+ continue;
+ }
+
// 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
@@ -707,8 +738,6 @@
ContextAssignment selectedContext = null;
final int allWorkTypes = getJobWorkTypes(nextPending);
final boolean pkgConcurrencyOkay = !isPkgConcurrencyLimitedLocked(nextPending);
- final boolean isTopEj = nextPending.shouldTreatAsExpeditedJob()
- && nextPending.lastEvaluatedBias == JobInfo.BIAS_TOP_APP;
final boolean isInOverage = projectedRunningCount > STANDARD_CONCURRENCY_LIMIT;
boolean startingJob = false;
if (idle.size() > 0) {
@@ -1177,6 +1206,15 @@
continue;
}
+ // Avoid overlapping job execution as much as possible.
+ if (isSimilarJobRunningLocked(nextPending)) {
+ if (DEBUG) {
+ Slog.w(TAG, "Avoiding execution of job because of similarly running one: "
+ + nextPending);
+ }
+ continue;
+ }
+
if (worker.getPreferredUid() != nextPending.getUid()) {
if (backupJob == null && !isPkgConcurrencyLimitedLocked(nextPending)) {
int allWorkTypes = getJobWorkTypes(nextPending);
@@ -1260,6 +1298,15 @@
continue;
}
+ // Avoid overlapping job execution as much as possible.
+ if (isSimilarJobRunningLocked(nextPending)) {
+ if (DEBUG) {
+ Slog.w(TAG, "Avoiding execution of job because of similarly running one: "
+ + nextPending);
+ }
+ continue;
+ }
+
if (isPkgConcurrencyLimitedLocked(nextPending)) {
continue;
}
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 358c327..cd70e88 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1208,12 +1208,22 @@
// This may throw a SecurityException.
jobStatus.prepareLocked();
+ final boolean canExecuteImmediately;
if (toCancel != null) {
// Implicitly replaces the existing job record with the new instance
- cancelJobImplLocked(toCancel, jobStatus, JobParameters.STOP_REASON_CANCELLED_BY_APP,
- JobParameters.INTERNAL_STOP_REASON_CANCELED, "job rescheduled by app");
+ final boolean wasJobExecuting = cancelJobImplLocked(toCancel, jobStatus,
+ JobParameters.STOP_REASON_CANCELLED_BY_APP,
+ JobParameters.INTERNAL_STOP_REASON_CANCELED,
+ "job rescheduled by app");
+ // Avoid overlapping job executions. Don't push for immediate execution if an old
+ // job with the same ID was running, but let TOP EJs start immediately.
+ canExecuteImmediately = !wasJobExecuting
+ || (jobStatus.isRequestedExpeditedJob()
+ && mUidBiasOverride.get(jobStatus.getSourceUid(), JobInfo.BIAS_DEFAULT)
+ == JobInfo.BIAS_TOP_APP);
} else {
startTrackingJobLocked(jobStatus, null);
+ canExecuteImmediately = true;
}
if (work != null) {
@@ -1256,7 +1266,12 @@
// list and try to run it.
mJobPackageTracker.notePending(jobStatus);
mPendingJobQueue.add(jobStatus);
- maybeRunPendingJobsLocked();
+ if (canExecuteImmediately) {
+ // Don't ask the JobConcurrencyManager to try to run the job immediately. The
+ // JobServiceContext will ask the JobConcurrencyManager for another job once
+ // it finishes cleaning up the old job.
+ maybeRunPendingJobsLocked();
+ }
} else {
evaluateControllerStatesLocked(jobStatus);
}
@@ -1377,8 +1392,10 @@
* is null, the cancelled job is removed outright from the system. If
* {@code incomingJob} is non-null, it replaces {@code cancelled} in the store of
* currently scheduled jobs.
+ *
+ * @return true if the cancelled job was running
*/
- private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob,
+ private boolean cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob,
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
cancelled.unprepareLocked();
@@ -1389,7 +1406,7 @@
}
mChangedJobList.remove(cancelled);
// Cancel if running.
- mConcurrencyManager.stopJobOnServiceContextLocked(
+ boolean wasRunning = mConcurrencyManager.stopJobOnServiceContextLocked(
cancelled, reason, internalReasonCode, debugReason);
// If this is a replacement, bring in the new version of the job
if (incomingJob != null) {
@@ -1397,6 +1414,7 @@
startTrackingJobLocked(incomingJob, cancelled);
}
reportActiveLocked();
+ return wasRunning;
}
void updateUidState(int uid, int procState) {
@@ -1755,7 +1773,7 @@
// same job ID), we remove it from the JobStore and tell the JobServiceContext to stop
// running the job. Once the job stops running, we then call this method again.
// TODO: rework code so we don't intentionally call this method twice for the same job
- Slog.w(TAG, "Job didn't exist in JobStore");
+ Slog.w(TAG, "Job didn't exist in JobStore: " + jobStatus.toShortString());
}
if (mReadyToRock) {
for (int i = 0; i < mControllers.size(); i++) {
@@ -3813,6 +3831,7 @@
// Double indent for readability
pw.increaseIndent();
pw.increaseIndent();
+ pw.println(job.toShortString());
job.dump(pw, true, nowElapsed);
pw.decreaseIndent();
pw.decreaseIndent();
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 80f3fea..c90291e 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -979,6 +979,7 @@
dumpBucketExpiryTimes(idpw, appUsageHistory, totalElapsedTime);
idpw.print(" lastJob=");
TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastJobRunTime, idpw);
+ idpw.print(" lastInformedBucket=" + appUsageHistory.lastInformedBucket);
if (appUsageHistory.lastRestrictAttemptElapsedTime > 0) {
idpw.print(" lastRestrictAttempt=");
TimeUtils.formatDuration(
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 c3d6b73..1891e06 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -1155,6 +1155,12 @@
final int appId = getAppId(packageName);
if (appId < 0) return;
+ final int minBucket = getAppMinBucket(packageName, appId, userId);
+ if (idle && minBucket < AppIdleHistory.IDLE_BUCKET_CUTOFF) {
+ Slog.e(TAG, "Tried to force an app to be idle when its min bucket is "
+ + standbyBucketToString(minBucket));
+ return;
+ }
final long elapsedRealtime = mInjector.elapsedRealtime();
final boolean previouslyIdle = isAppIdleFiltered(packageName, appId,
@@ -1166,12 +1172,10 @@
final boolean stillIdle = isAppIdleFiltered(packageName, appId,
userId, elapsedRealtime);
// Inform listeners if necessary
+ maybeInformListeners(packageName, userId, elapsedRealtime, standbyBucket,
+ REASON_MAIN_FORCED_BY_USER, false);
if (previouslyIdle != stillIdle) {
- maybeInformListeners(packageName, userId, elapsedRealtime, standbyBucket,
- REASON_MAIN_FORCED_BY_USER, false);
- if (!stillIdle) {
- notifyBatteryStats(packageName, userId, idle);
- }
+ notifyBatteryStats(packageName, userId, stillIdle);
}
}
@@ -1934,6 +1938,8 @@
}
mAppIdleHistory.setAppStandbyBucket(
packageName, userId, elapsedRealtime, newBucket, newReason);
+ maybeInformListeners(packageName, userId, elapsedRealtime, newBucket,
+ newReason, false);
}
}
@@ -2490,6 +2496,8 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_INFORM_LISTENERS:
+ // TODO(230875908): Properly notify BatteryStats when apps change from active to
+ // idle, and vice versa
StandbyUpdateRecord r = (StandbyUpdateRecord) msg.obj;
informListeners(r.packageName, r.userId, r.bucket, r.reason,
r.isUserInteraction);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4681d49..36e1c94 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -314,7 +314,6 @@
public final class NotificationChannel implements android.os.Parcelable {
method public int getOriginalImportance();
method public boolean isImportanceLockedByCriticalDeviceFunction();
- method public boolean isImportanceLockedByOEM();
method public void lockFields(int);
method public void setDeleted(boolean);
method public void setDeletedTimeMs(long);
@@ -800,6 +799,7 @@
method public boolean hasRequestForegroundServiceExemption();
method public boolean isPrivilegedApp();
method public boolean isSystemApp();
+ method public void setEnableOnBackInvokedCallback(boolean);
field public static final int PRIVATE_FLAG_PRIVILEGED = 8; // 0x8
field public int privateFlags;
}
@@ -919,7 +919,7 @@
field public int id;
field public String lastLoggedInFingerprint;
field public long lastLoggedInTime;
- field public String name;
+ field @Nullable public String name;
field public boolean partial;
field public boolean preCreated;
field public int profileBadge;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c7c654a..3b1943b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2537,8 +2537,8 @@
* restriction} for a certain app-op.
*/
private static RestrictionBypass[] sOpAllowSystemRestrictionBypass = new RestrictionBypass[] {
- null, //COARSE_LOCATION
- null, //FINE_LOCATION
+ new RestrictionBypass(true, false, false), //COARSE_LOCATION
+ new RestrictionBypass(true, false, false), //FINE_LOCATION
null, //GPS
null, //VIBRATE
null, //READ_CONTACTS
@@ -2547,7 +2547,7 @@
null, //WRITE_CALL_LOG
null, //READ_CALENDAR
null, //WRITE_CALENDAR
- new RestrictionBypass(true, false), //WIFI_SCAN
+ new RestrictionBypass(false, true, false), //WIFI_SCAN
null, //POST_NOTIFICATION
null, //NEIGHBORING_CELLS
null, //CALL_PHONE
@@ -2561,10 +2561,10 @@
null, //READ_ICC_SMS
null, //WRITE_ICC_SMS
null, //WRITE_SETTINGS
- new RestrictionBypass(true, false), //SYSTEM_ALERT_WINDOW
+ new RestrictionBypass(false, true, false), //SYSTEM_ALERT_WINDOW
null, //ACCESS_NOTIFICATIONS
null, //CAMERA
- new RestrictionBypass(false, true), //RECORD_AUDIO
+ new RestrictionBypass(false, false, true), //RECORD_AUDIO
null, //PLAY_AUDIO
null, //READ_CLIPBOARD
null, //WRITE_CLIPBOARD
@@ -2582,7 +2582,7 @@
null, //MONITOR_HIGH_POWER_LOCATION
null, //GET_USAGE_STATS
null, //MUTE_MICROPHONE
- new RestrictionBypass(true, false), //TOAST_WINDOW
+ new RestrictionBypass(false, true, false), //TOAST_WINDOW
null, //PROJECT_MEDIA
null, //ACTIVATE_VPN
null, //WALLPAPER
@@ -2614,7 +2614,7 @@
null, // ACCEPT_HANDOVER
null, // MANAGE_IPSEC_HANDOVERS
null, // START_FOREGROUND
- new RestrictionBypass(true, false), // BLUETOOTH_SCAN
+ new RestrictionBypass(false, true, false), // BLUETOOTH_SCAN
null, // USE_BIOMETRIC
null, // ACTIVITY_RECOGNITION
null, // SMS_FINANCIAL_TRANSACTIONS
@@ -3331,6 +3331,9 @@
* @hide
*/
public static class RestrictionBypass {
+ /** Does the app need to be system uid to bypass the restriction */
+ public boolean isSystemUid;
+
/** Does the app need to be privileged to bypass the restriction */
public boolean isPrivileged;
@@ -3340,12 +3343,14 @@
*/
public boolean isRecordAudioRestrictionExcept;
- public RestrictionBypass(boolean isPrivileged, boolean isRecordAudioRestrictionExcept) {
+ public RestrictionBypass(boolean isSystemUid, boolean isPrivileged,
+ boolean isRecordAudioRestrictionExcept) {
+ this.isSystemUid = isSystemUid;
this.isPrivileged = isPrivileged;
this.isRecordAudioRestrictionExcept = isRecordAudioRestrictionExcept;
}
- public static RestrictionBypass UNRESTRICTED = new RestrictionBypass(true, true);
+ public static RestrictionBypass UNRESTRICTED = new RestrictionBypass(false, true, true);
}
/**
diff --git a/core/java/android/app/LocaleConfig.java b/core/java/android/app/LocaleConfig.java
index 436eac3..7c83d58 100644
--- a/core/java/android/app/LocaleConfig.java
+++ b/core/java/android/app/LocaleConfig.java
@@ -45,7 +45,9 @@
* referenced in the manifest via {@code android:localeConfig} on
* {@code <application>}.
*
- * For more information, see TODO(b/214154050): add link to guide
+ * <p>For more information, see
+ * <a href="https://developer.android.com/about/versions/13/features/app-languages#use-localeconfig">
+ * the section on per-app language preferences</a>.
*
* @attr ref android.R.styleable#LocaleConfig_Locale_name
* @attr ref android.R.styleable#AndroidManifestApplication_localeConfig
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 974d20a..e820733 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -7770,10 +7770,11 @@
* user will always see the normal notification view.
*
* <p>
- * If the app is targeting Android P and above, it is required to use the {@link Person}
- * class in order to get an optimal rendering of the notification and its avatars. For
- * conversations involving multiple people, the app should also make sure that it marks the
- * conversation as a group with {@link #setGroupConversation(boolean)}.
+ * If the app is targeting Android {@link android.os.Build.VERSION_CODES#P} and above, it is
+ * required to use the {@link Person} class in order to get an optimal rendering of the
+ * notification and its avatars. For conversations involving multiple people, the app should
+ * also make sure that it marks the conversation as a group with
+ * {@link #setGroupConversation(boolean)}.
*
* <p>
* This class is a "rebuilder": It attaches to a Builder object and modifies its behavior.
@@ -7846,8 +7847,8 @@
* @param user Required - The person displayed for any messages that are sent by the
* user. Any messages added with {@link #addMessage(Notification.MessagingStyle.Message)}
* who don't have a Person associated with it will be displayed as if they were sent
- * by this user. The user also needs to have a valid name associated with it, which will
- * be enforced starting in Android P.
+ * by this user. The user also needs to have a valid name associated with it, which is
+ * enforced starting in Android {@link android.os.Build.VERSION_CODES#P}.
*/
public MessagingStyle(@NonNull Person user) {
mUser = user;
@@ -7904,9 +7905,9 @@
/**
* Sets the title to be displayed on this conversation. May be set to {@code null}.
*
- * <p>Starting in {@link Build.VERSION_CODES#R, this conversation title will be ignored if a
- * valid shortcutId is added via {@link Notification.Builder#setShortcutId(String)}. In this
- * case, {@link ShortcutInfo#getLongLabel()} (or, if missing,
+ * <p>Starting in {@link Build.VERSION_CODES#R}, this conversation title will be ignored
+ * if a valid shortcutId is added via {@link Notification.Builder#setShortcutId(String)}.
+ * In this case, {@link ShortcutInfo#getLongLabel()} (or, if missing,
* {@link ShortcutInfo#getShortLabel()}) will be shown as the conversation title
* instead.
*
@@ -8065,7 +8066,7 @@
}
/**
- * Gets the list of {@code Message} objects that represent the notification
+ * Gets the list of {@code Message} objects that represent the notification.
*/
public List<Message> getMessages() {
return mMessages;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 91ab19b..6f0b03a 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -867,14 +867,6 @@
* @hide
*/
@TestApi
- public boolean isImportanceLockedByOEM() {
- return mImportanceLockedByOEM;
- }
-
- /**
- * @hide
- */
- @TestApi
public boolean isImportanceLockedByCriticalDeviceFunction() {
return mImportanceLockedDefaultApp;
}
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index a8ae191..32207af 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -110,19 +110,6 @@
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- // TODO(b/225076204): Remove the following four test cases after fixing the test fail.
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_createDetectorTwiceQuickly_triggerSuccess"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_onDetectFromExternalSource_success"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_createDetectorTwiceQuickly_triggerSuccess"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_onDetectFromMic_success"
}
],
"file_patterns": ["(/|^)VoiceInteract[^/]*"]
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index b7b93aa..0a2b421 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1811,10 +1811,6 @@
* #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra contain {@link
* #PROVISIONING_MODE_MANAGED_PROFILE} and {@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}.
*
- * <p>Also, if this flag is set, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity
- * will not receive the {@link #EXTRA_PROVISIONING_IMEI} and {@link
- * #EXTRA_PROVISIONING_SERIAL_NUMBER} extras.
- *
* <p>This flag can be combined with {@link #FLAG_SUPPORTED_MODES_PERSONALLY_OWNED}. In
* that case, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity will have
* the {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra contain {@link
@@ -1834,6 +1830,10 @@
* activity to have the {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra
* contain only {@link #PROVISIONING_MODE_MANAGED_PROFILE}.
*
+ * <p>Also, if this flag is set, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity
+ * will not receive the {@link #EXTRA_PROVISIONING_IMEI} and {@link
+ * #EXTRA_PROVISIONING_SERIAL_NUMBER} extras.
+ *
* <p>This flag can be combined with {@link #FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED}. In
* that case, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity will have the
* {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra contain {@link
@@ -3375,6 +3375,55 @@
RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED = 3;
/**
+ * An {@code int} extra that specifies one of {@link
+ * #ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING} or {@link
+ * #ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING}.
+ *
+ * <p>The failure strategy specifies how the platform should handle a failed device policy
+ * management role holder update via {@link
+ * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER} when {@link
+ * #EXTRA_PROVISIONING_ALLOW_OFFLINE} is not set or set to {@code false}.
+ *
+ * <p>This extra may be supplied as part of the {@link
+ * #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER} result intent.
+ *
+ * <p>Default value is {@link #ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING}.
+ *
+ * @hide
+ */
+ public static final String EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY =
+ "android.app.extra.ROLE_HOLDER_UPDATE_FAILURE_STRATEGY";
+
+ /**
+ * Possible values for {@link #EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY}.
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_" }, value = {
+ ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING,
+ ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RoleHolderUpdateFailureStrategy {}
+
+ /**
+ * A value for {@link #EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY} indicating that upon
+ * failure to update the role holder, provisioning should fail.
+ *
+ * @hide
+ */
+ public static final int ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FAIL_PROVISIONING = 1;
+
+ /**
+ * A value for {@link #EXTRA_ROLE_HOLDER_UPDATE_FAILURE_STRATEGY} indicating that upon
+ * failure to update the role holder, provisioning should fallback to be platform-driven.
+ *
+ * @hide
+ */
+ public static final int ROLE_HOLDER_UPDATE_FAILURE_STRATEGY_FALLBACK_TO_PLATFORM_PROVISIONING =
+ 2;
+
+ /**
* An {@code int} extra which contains the result code of the last attempt to update
* the device policy management role holder via {@link
* #ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER}.
@@ -13200,8 +13249,9 @@
* Called by a device owner, profile owner of a managed profile or delegated app with
* {@link #DELEGATION_NETWORK_LOGGING} to control the network logging feature.
*
- * <p> When network logging is enabled by a profile owner, the network logs will only include
- * work profile network activity, not activity on the personal profile.
+ * <p> Supported for a device owner from Android 8. Supported for a profile owner of a managed
+ * profile from Android 12. When network logging is enabled by a profile owner, the network logs
+ * will only include work profile network activity, not activity on the personal profile.
*
* <p> Network logs contain DNS lookup and connect() library call events. The following library
* functions are recorded while network logging is active:
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index ea30ef7..c8033fa 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -863,12 +863,6 @@
PREFIX + "REMOVE_AND_UNINSTALL_DEVICE_ADMIN";
/**
- * Title for selecting device admin apps
- */
- public static final String SELECT_DEVICE_ADMIN_APPS =
- PREFIX + "SELECT_DEVICE_ADMIN_APPS";
-
- /**
* Message when there are no available device admin apps to display
*/
public static final String NO_DEVICE_ADMINS = PREFIX + "NO_DEVICE_ADMINS";
@@ -910,11 +904,6 @@
PREFIX + "ACTIVE_DEVICE_ADMIN_WARNING";
/**
- * Title for screen to set a profile owner
- */
- public static final String SET_PROFILE_OWNER_TITLE = PREFIX + "SET_PROFILE_OWNER_TITLE";
-
- /**
* Simplified title for dialog to set a profile owner
*/
public static final String SET_PROFILE_OWNER_DIALOG_TITLE =
@@ -1173,7 +1162,93 @@
/**
* Header for items under the personal user
*/
- public static final String PERSONAL_CATEGORY_HEADER = PREFIX + "category_personal";
+ public static final String PERSONAL_CATEGORY_HEADER =
+ PREFIX + "PERSONAL_CATEGORY_HEADER";
+
+ /**
+ * Text to indicate work notification content will be shown on the lockscreen.
+ */
+ public static final String LOCK_SCREEN_SHOW_WORK_NOTIFICATION_CONTENT =
+ PREFIX + "LOCK_SCREEN_SHOW_WORK_NOTIFICATION_CONTENT";
+
+ /**
+ * Text to indicate work notification content will be shown on the lockscreen.
+ */
+ public static final String LOCK_SCREEN_HIDE_WORK_NOTIFICATION_CONTENT =
+ PREFIX + "LOCK_SCREEN_HIDE_WORK_NOTIFICATION_CONTENT";
+
+ /**
+ * Text for toggle to enable auto-sycing personal data
+ */
+ public static final String AUTO_SYNC_PERSONAL_DATA = PREFIX
+ + "AUTO_SYNC_PERSONAL_DATA";
+
+ /**
+ * Text for toggle to enable auto-sycing work data
+ */
+ public static final String AUTO_SYNC_WORK_DATA = PREFIX + "AUTO_SYNC_WORK_DATA";
+
+ /**
+ * Summary for "More security settings" section when a work profile is on the device.
+ */
+ public static final String MORE_SECURITY_SETTINGS_WORK_PROFILE_SUMMARY = PREFIX
+ + "MORE_SECURITY_SETTINGS_WORK_PROFILE_SUMMARY";
+
+ /**
+ * Title for screen asking the user to choose a type of screen lock (such as a pattern,
+ * PIN, or password) that they need to enter to use their work apps
+ */
+ public static final String LOCK_SETTINGS_NEW_PROFILE_LOCK_TITLE = PREFIX
+ + "LOCK_SETTINGS_NEW_PROFILE_LOCK_TITLE";
+
+ /**
+ * Title for screen asking the user to update the type of screen lock (such as a
+ * pattern, PIN, or password) that they need to enter to use their work apps
+ */
+ public static final String LOCK_SETTINGS_UPDATE_PROFILE_LOCK_TITLE = PREFIX
+ + "LOCK_SETTINGS_UPDATE_PROFILE_LOCK_TITLE";
+
+ /**
+ * Title for section listing information that can be seen by organization
+ */
+ public static final String INFORMATION_SEEN_BY_ORGANIZATION_TITLE = PREFIX
+ + "INFORMATION_SEEN_BY_ORGANIZATION_TITLE";
+
+ /**
+ * Title for section listing changes made by the organization.
+ */
+ public static final String CHANGES_BY_ORGANIZATION_TITLE =
+ PREFIX + "CHANGES_BY_ORGANIZATION_TITLE";
+
+ /**
+ * Footer for enterprise privacy screen.
+ */
+ public static final String ENTERPRISE_PRIVACY_FOOTER =
+ PREFIX + "ENTERPRISE_PRIVACY_FOOTER";
+
+ /**
+ * Title for spell checker settings for work.
+ */
+ public static final String SPELL_CHECKER_FOR_WORK =
+ PREFIX + "SPELL_CHECKER_FOR_WORK";
+
+ /**
+ * Title for personal dictionary for work settings.
+ */
+ public static final String PERSONAL_DICTIONARY_FOR_WORK =
+ PREFIX + "PERSONAL_DICTIONARY_FOR_WORK";
+
+ /**
+ * Summary for switch preference to indicate it is disabled by the admin
+ */
+ public static final String DISABLED_BY_ADMIN_SWITCH_SUMMARY =
+ PREFIX + "DISABLED_BY_ADMIN_SWITCH_SUMMARY";
+
+ /**
+ * Summary for switch preference to indicate it is enabled by the admin
+ */
+ public static final String ENABLED_BY_ADMIN_SWITCH_SUMMARY =
+ PREFIX + "ENABLED_BY_ADMIN_SWITCH_SUMMARY";
}
/**
diff --git a/core/java/android/app/admin/ProvisioningIntentHelper.java b/core/java/android/app/admin/ProvisioningIntentHelper.java
index fbad90c..1c38559 100644
--- a/core/java/android/app/admin/ProvisioningIntentHelper.java
+++ b/core/java/android/app/admin/ProvisioningIntentHelper.java
@@ -17,8 +17,10 @@
package android.app.admin;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
+import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TRIGGER;
import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC;
import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_NFC;
@@ -36,12 +38,14 @@
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import android.util.Log;
import java.io.IOException;
import java.io.StringReader;
import java.util.Enumeration;
import java.util.Properties;
+import java.util.Set;
/**
* Utility class that provides functionality to create provisioning intents from nfc intents.
@@ -124,12 +128,46 @@
ComponentName componentName = ComponentName.unflattenFromString(
properties.getProperty(propertyName));
bundle.putParcelable(propertyName, componentName);
+ } else if (EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE.equals(propertyName)
+ || EXTRA_PROVISIONING_ROLE_HOLDER_EXTRAS_BUNDLE.equals(propertyName)) {
+ try {
+ bundle.putParcelable(propertyName,
+ deserializeExtrasBundle(properties, propertyName));
+ } catch (IOException e) {
+ Log.e(TAG,
+ "Failed to parse " + propertyName + ".", e);
+ }
}
else {
bundle.putString(propertyName, properties.getProperty(propertyName));
}
}
+ /**
+ * Get a {@link PersistableBundle} from a {@code String} property in a {@link Properties}
+ * object.
+ * @param properties the source of the extra
+ * @param extraName key into the {@link Properties} object
+ * @return the {@link PersistableBundle} or {@code null} if there was no property with the
+ * given name
+ * @throws IOException if there was an error parsing the property
+ */
+ private static PersistableBundle deserializeExtrasBundle(
+ Properties properties, String extraName) throws IOException {
+ String serializedExtras = properties.getProperty(extraName);
+ if (serializedExtras == null) {
+ return null;
+ }
+ Properties bundleProperties = new Properties();
+ bundleProperties.load(new StringReader(serializedExtras));
+ PersistableBundle extrasBundle = new PersistableBundle(bundleProperties.size());
+ Set<String> propertyNames = bundleProperties.stringPropertyNames();
+ for (String propertyName : propertyNames) {
+ extrasBundle.putString(propertyName, bundleProperties.getProperty(propertyName));
+ }
+ return extrasBundle;
+ }
+
private static Intent createProvisioningIntentFromBundle(Bundle bundle) {
requireNonNull(bundle);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4d56c1d..907db7d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -513,10 +513,23 @@
* restart. There is no guarantee this will be respected, as the system
* tries to balance such requests from one app vs. the importance of
* keeping other apps around.
+ *
+ * @deprecated Repurposed to {@link #BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE}.
*/
+ @Deprecated
public static final int BIND_VISIBLE = 0x10000000;
/**
+ * @hide Flag for {@link #bindService}: Treat the binding as hosting a foreground service
+ * and also visible to the user. That is, the app hosting the service will get its process state
+ * bumped to the {@link android.app.ActivityManager#PROCESS_STATE_FOREGROUND_SERVICE},
+ * and it's considered as visible to the user, thus less likely to be expunged from memory
+ * on low memory situations. This is intented for use by processes with the process state
+ * better than the {@link android.app.ActivityManager#PROCESS_STATE_TOP}.
+ */
+ public static final int BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE = 0x10000000;
+
+ /**
* @hide
* Flag for {@link #bindService}: Consider this binding to be causing the target
* process to be showing UI, so it will be do a UI_HIDDEN memory trim when it goes
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 2961b55..24c3836 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2752,4 +2752,21 @@
mKnownActivityEmbeddingCerts.add(knownCert.toUpperCase(Locale.US));
}
}
+
+ /**
+ * Sets whether the application will use the {@link android.window.OnBackInvokedCallback}
+ * navigation system instead of the {@link android.view.KeyEvent#KEYCODE_BACK} and related
+ * callbacks. Intended to be used from tests only.
+ *
+ * @see #isOnBackInvokedCallbackEnabled()
+ * @hide
+ */
+ @TestApi
+ public void setEnableOnBackInvokedCallback(boolean isEnable) {
+ if (isEnable) {
+ privateFlagsExt |= PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK;
+ } else {
+ privateFlagsExt &= ~PRIVATE_FLAG_EXT_ENABLE_ON_BACK_INVOKED_CALLBACK;
+ }
+ }
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 44dc28d..52e64e8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2618,6 +2618,15 @@
return Build.VERSION_CODES.CUR_DEVELOPMENT;
}
+ // STOPSHIP: hack for the pre-release SDK
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ targetCode)) {
+ Slog.w(TAG, "Package requires development platform " + targetCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return Build.VERSION.SDK_INT;
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
outError[0] = "Requires development platform " + targetCode
@@ -2689,6 +2698,15 @@
return Build.VERSION_CODES.CUR_DEVELOPMENT;
}
+ // STOPSHIP: hack for the pre-release SDK
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ minCode)) {
+ Slog.w(TAG, "Package requires min development platform " + minCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return Build.VERSION.SDK_INT;
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
outError[0] = "Requires development platform " + minCode
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 76e9fcb..d6e13ac 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;
@@ -170,7 +171,7 @@
@UnsupportedAppUsage
public int serialNumber;
@UnsupportedAppUsage
- public String name;
+ public @Nullable String name;
@UnsupportedAppUsage
public String iconPath;
@UnsupportedAppUsage
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index cb55e30..20a4fdf 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -567,9 +567,14 @@
targetCode = minCode;
}
+ boolean allowUnknownCodenames = false;
+ if ((flags & FrameworkParsingPackageUtils.PARSE_APK_IN_APEX) != 0) {
+ allowUnknownCodenames = true;
+ }
+
ParseResult<Integer> targetResult = FrameworkParsingPackageUtils.computeTargetSdkVersion(
targetVer, targetCode, SDK_CODENAMES, input,
- /* allowUnknownCodenames= */ false);
+ allowUnknownCodenames);
if (targetResult.isError()) {
return input.error(targetResult);
}
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 6d74b81..8cc4cdb 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -58,6 +58,7 @@
private static final int MAX_FILE_NAME_SIZE = 223;
public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
+ public static final int PARSE_APK_IN_APEX = 1 << 9;
/**
* Check if the given name is valid.
@@ -315,6 +316,15 @@
return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
}
+ // STOPSHIP: hack for the pre-release SDK
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ minCode)) {
+ Slog.w(TAG, "Parsed package requires min development platform " + minCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return input.success(Build.VERSION.SDK_INT);
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
@@ -367,16 +377,29 @@
return input.success(targetVers);
}
- if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) {
- return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
- }
-
// If it's a pre-release SDK and the codename matches this platform, it
// definitely targets this SDK.
if (matchTargetCode(platformSdkCodenames, targetCode)) {
return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
}
+ // STOPSHIP: hack for the pre-release SDK
+ if (platformSdkCodenames.length == 0
+ && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+ targetCode)) {
+ Slog.w(TAG, "Parsed package requires development platform " + targetCode
+ + ", returning current version " + Build.VERSION.SDK_INT);
+ return input.success(Build.VERSION.SDK_INT);
+ }
+
+ try {
+ if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) {
+ return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+ }
+ } catch (IllegalArgumentException e) {
+ return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK");
+ }
+
// Otherwise, we're looking at an incompatible pre-release SDK.
if (platformSdkCodenames.length > 0) {
return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
diff --git a/core/java/android/hardware/ISensorPrivacyManager.aidl b/core/java/android/hardware/ISensorPrivacyManager.aidl
index a392afd..9cf329c 100644
--- a/core/java/android/hardware/ISensorPrivacyManager.aidl
+++ b/core/java/android/hardware/ISensorPrivacyManager.aidl
@@ -50,5 +50,7 @@
void suppressToggleSensorPrivacyReminders(int userId, int sensor, IBinder token,
boolean suppress);
+ boolean requiresAuthentication();
+
void showSensorUseDialog(int sensor);
}
\ No newline at end of file
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index 0460e58..99b58c9 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -327,6 +327,8 @@
@NonNull
private boolean mToggleListenerRegistered = false;
+ private Boolean mRequiresAuthentication = null;
+
/**
* Private constructor to ensure only a single instance is created.
*/
@@ -761,6 +763,23 @@
}
/**
+ * @return whether the device is required to be unlocked to change software state.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
+ public boolean requiresAuthentication() {
+ if (mRequiresAuthentication == null) {
+ try {
+ mRequiresAuthentication = mService.requiresAuthentication();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return mRequiresAuthentication;
+ }
+
+ /**
* If sensor privacy for the provided sensor is enabled then this call will show the user the
* dialog which is shown when an application attempts to use that sensor. If privacy isn't
* enabled then this does nothing.
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index b05e6d1..a90eb88 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1058,7 +1058,7 @@
* must select one unique size from this metadata to use (e.g., preview and recording streams
* must have the same size). Otherwise, the high speed capture session creation will fail.</p>
* <p>The min and max fps will be multiple times of 30fps.</p>
- * <p>High speed video streaming extends significant performance pressue to camera hardware,
+ * <p>High speed video streaming extends significant performance pressure to camera hardware,
* to achieve efficient high speed streaming, the camera device may have to aggregate
* multiple frames together and send to camera device for processing where the request
* controls are same for all the frames in this batch. Max batch size indicates
@@ -1143,7 +1143,7 @@
* <p>Range of boosts for {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} supported
* by this camera device.</p>
* <p>Devices support post RAW sensitivity boost will advertise
- * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} key for controling
+ * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} key for controlling
* post RAW sensitivity boost.</p>
* <p>This key will be <code>null</code> for devices that do not support any RAW format
* outputs. For devices that do support RAW format outputs, this key will always
@@ -1323,7 +1323,7 @@
* <p>Maximum flashlight brightness level.</p>
* <p>If this value is greater than 1, then the device supports controlling the
* flashlight brightness level via
- * {android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel}.
+ * {@link android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel }.
* If this value is equal to 1, flashlight brightness control is not supported.
* The value for this key will be null for devices with no flash unit.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -1335,7 +1335,7 @@
/**
* <p>Default flashlight brightness level to be set via
- * {android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel}.</p>
+ * {@link android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel }.</p>
* <p>If flash unit is available this will be greater than or equal to 1 and less
* or equal to <code>{@link CameraCharacteristics#FLASH_INFO_STRENGTH_MAXIMUM_LEVEL android.flash.info.strengthMaximumLevel}</code>.</p>
* <p>Setting flashlight brightness above the default level
@@ -1376,7 +1376,7 @@
* camera device.</p>
* <p>This list will include at least one non-zero resolution, plus <code>(0,0)</code> for indicating no
* thumbnail should be generated.</p>
- * <p>Below condiditions will be satisfied for this size list:</p>
+ * <p>Below conditions will be satisfied for this size list:</p>
* <ul>
* <li>The sizes will be sorted by increasing pixel area (width x height).
* If several resolutions have the same area, they will be sorted by increasing width.</li>
@@ -1982,7 +1982,7 @@
* the camera device. Using more streams simultaneously may require more hardware and
* CPU resources that will consume more power. The image format for an output stream can
* be any supported format provided by android.scaler.availableStreamConfigurations.
- * The formats defined in android.scaler.availableStreamConfigurations can be catergorized
+ * The formats defined in android.scaler.availableStreamConfigurations can be categorized
* into the 3 stream types as below:</p>
* <ul>
* <li>Processed (but stalling): any non-RAW format with a stallDurations > 0.
@@ -2324,7 +2324,7 @@
* but clients should be aware and expect delays during their application.
* An example usage scenario could look like this:</p>
* <ul>
- * <li>The camera client starts by quering the session parameter key list via
+ * <li>The camera client starts by querying the session parameter key list via
* {@link android.hardware.camera2.CameraCharacteristics#getAvailableSessionKeys }.</li>
* <li>Before triggering the capture session create sequence, a capture request
* must be built via
@@ -2379,7 +2379,7 @@
* {@link android.hardware.camera2.CameraCharacteristics#getKeys } that require camera clients
* to acquire the {@link android.Manifest.permission#CAMERA } permission before calling
* {@link android.hardware.camera2.CameraManager#getCameraCharacteristics }. If the
- * permission is not held by the camera client, then the values of the repsective properties
+ * permission is not held by the camera client, then the values of the respective properties
* will not be present in {@link android.hardware.camera2.CameraCharacteristics }.</p>
* <p>This key is available on all devices.</p>
* @hide
@@ -2759,7 +2759,7 @@
* </table>
* <p>For applications targeting SDK version 31 or newer, if the mobile device declares to be
* media performance class 12 or higher by setting
- * {@link android.os.Build.VERSION_CDOES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger,
+ * {@link android.os.Build.VERSION_CODES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger,
* the primary camera devices (first rear/front camera in the camera ID list) will not
* support JPEG sizes smaller than 1080p. If the application configures a JPEG stream
* smaller than 1080p, the camera device will round up the JPEG image size to at least
@@ -2833,7 +2833,7 @@
* </table>
* <p>For applications targeting SDK version 31 or newer, if the mobile device doesn't declare
* to be media performance class 12 or better by setting
- * {@link android.os.Build.VERSION_CDOES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger,
+ * {@link android.os.Build.VERSION_CODES.MEDIA_PERFORMANCE_CLASS } to be 31 or larger,
* or if the camera device isn't a primary rear/front camera, the minimum required output
* stream configurations are the same as for applications targeting SDK version older than
* 31.</p>
@@ -3485,14 +3485,16 @@
* to output different resolution images depending on the current active physical camera or
* pixel mode. With multi-resolution input streams, the camera device can reprocess images
* of different resolutions from different physical cameras or sensor pixel modes.</p>
- * <p>When set to TRUE:
- * * For a logical multi-camera, the camera framework derives
+ * <p>When set to TRUE:</p>
+ * <ul>
+ * <li>For a logical multi-camera, the camera framework derives
* {@link CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP android.scaler.multiResolutionStreamConfigurationMap} by combining the
* android.scaler.physicalCameraMultiResolutionStreamConfigurations from its physical
- * cameras.
- * * For an ultra-high resolution sensor camera, the camera framework directly copies
+ * cameras.</li>
+ * <li>For an ultra-high resolution sensor camera, the camera framework directly copies
* the value of android.scaler.physicalCameraMultiResolutionStreamConfigurations to
- * {@link CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP android.scaler.multiResolutionStreamConfigurationMap}.</p>
+ * {@link CameraCharacteristics#SCALER_MULTI_RESOLUTION_STREAM_CONFIGURATION_MAP android.scaler.multiResolutionStreamConfigurationMap}.</li>
+ * </ul>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
* <p><b>Limited capability</b> -
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3513,7 +3515,7 @@
* capture, video record for encoding the camera output for the purpose of future playback,
* and video call for live realtime video conferencing.</p>
* <p>With this flag, the camera device can optimize the image processing pipeline
- * parameters, such as tuning, sensor mode, and ISP settings, indepedent of
+ * parameters, such as tuning, sensor mode, and ISP settings, independent of
* the properties of the immediate camera output surface. For example, if the output
* surface is a SurfaceTexture, the stream use case flag can be used to indicate whether
* the camera frames eventually go to display, video encoder,
@@ -3535,7 +3537,7 @@
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE }
* capability is documented in the camera device
* {@link android.hardware.camera2.CameraDevice#createCaptureSession guideline}. The
- * application is strongly recommended to use one of the guaranteed stream combintations.
+ * application is strongly recommended to use one of the guaranteed stream combinations.
* If the application creates a session with a stream combination not in the guaranteed
* list, or with mixed DEFAULT and non-DEFAULT use cases within the same session,
* the camera device may ignore some stream use cases due to hardware constraints
@@ -5209,7 +5211,7 @@
* EXTERIOR_* value.</p>
* <p>If a camera has INTERIOR_OTHER or EXTERIOR_OTHER, or more than one camera is at the
* same location and facing the same direction, their static metadata will list the
- * following entries, so that applications can determain their lenses' exact facing
+ * following entries, so that applications can determine their lenses' exact facing
* directions:</p>
* <ul>
* <li>{@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference}</li>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 40565b0..eb8c73a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -409,7 +409,7 @@
/**
* <p>The value of {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation} is relative to the origin of the
- * automotive sensor coodinate system, which is at the center of the rear axle.</p>
+ * automotive sensor coordinate system, which is at the center of the rear axle.</p>
*
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#LENS_POSE_REFERENCE
@@ -683,7 +683,7 @@
* captured at the same rate as the maximum-size YUV_420_888 resolution is.</p>
* <p>If the device supports the PRIVATE_REPROCESSING capability, then the same guarantees
* as for the YUV_420_888 format also apply to the {@link android.graphics.ImageFormat#PRIVATE } format.</p>
- * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is guaranted to have a value between 0
+ * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is guaranteed to have a value between 0
* and 4, inclusive. {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable}
* are also guaranteed to be <code>true</code> so burst capture with these two locks ON yields
* consistent image output.</p>
@@ -843,7 +843,7 @@
* {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }.</li>
* <li>The FPS ranges are selected from {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoFpsRanges }.</li>
* </ul>
- * <p>When above conditions are NOT satistied,
+ * <p>When above conditions are NOT satisfied,
* {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession }
* will fail.</p>
* <p>Switching to a FPS range that has different maximum FPS may trigger some camera device
@@ -986,7 +986,7 @@
* non-active physical cameras. For example, if the logical camera has a wide-ultrawide
* configuration where the wide lens is the default, when the crop region is set to the
* logical camera's active array size, (and the zoom ratio set to 1.0 starting from
- * Android 11), a physical stream for the ultrawide camera may prefer outputing images
+ * Android 11), a physical stream for the ultrawide camera may prefer outputting images
* with larger field-of-view than that of the wide camera for better stereo matching
* margin or more robust motion tracking. At the same time, the physical non-RAW streams'
* field of view must not be smaller than the requested crop region and zoom ratio, as
@@ -1175,21 +1175,23 @@
* when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to
* {@link android.hardware.camera2.CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION }),
* the <code>RAW_SENSOR</code> stream will have a regular bayer pattern.</p>
- * <p>This capability requires the camera device to support the following :
- * * The {@link android.hardware.camera2.params.StreamConfigurationMap } mentioned below
+ * <p>This capability requires the camera device to support the following :</p>
+ * <ul>
+ * <li>The {@link android.hardware.camera2.params.StreamConfigurationMap } mentioned below
* refers to the one, described by
- * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>.
- * * One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.
- * * {@link android.graphics.ImageFormat#RAW_SENSOR } is supported as an output/input
+ * <code>{@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}</code>.</li>
+ * <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
+ * <li>{@link android.graphics.ImageFormat#RAW_SENSOR } is supported as an output/input
* format, that is, {@link android.graphics.ImageFormat#RAW_SENSOR } is included in the
- * lists of formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.
- * * {@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
- * returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.
- * * Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.RAW_SENSOR)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.RAW_SENSOR)}
- * * Using {@link android.graphics.ImageFormat#RAW_SENSOR } does not cause a frame rate
- * drop relative to the sensor's maximum capture rate (at that resolution).
- * * No CaptureRequest controls will be applicable when a request has an input target
- * with {@link android.graphics.ImageFormat#RAW_SENSOR } format.</p>
+ * lists of formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+ * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+ * returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+ * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.RAW_SENSOR)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.RAW_SENSOR)}</li>
+ * <li>Using {@link android.graphics.ImageFormat#RAW_SENSOR } does not cause a frame rate
+ * drop relative to the sensor's maximum capture rate (at that resolution).</li>
+ * <li>No CaptureRequest controls will be applicable when a request has an input target
+ * with {@link android.graphics.ImageFormat#RAW_SENSOR } format.</li>
+ * </ul>
*
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
@@ -1205,16 +1207,18 @@
* {@link android.hardware.camera2.params.DynamicRangeProfiles#getSupportedProfiles }.
* They can be configured as part of the capture session initialization via
* {@link android.hardware.camera2.params.OutputConfiguration#setDynamicRangeProfile }.
- * Cameras that enable this capability must also support the following:
- * * Profile {@link android.hardware.camera2.params.DynamicRangeProfiles#HLG10 }
- * * All mandatory stream combinations for this specific capability as per
- * documentation {@link android.hardware.camera2.CameraDevice#createCaptureSession }
- * * In case the device is not able to capture some combination of supported
+ * Cameras that enable this capability must also support the following:</p>
+ * <ul>
+ * <li>Profile {@link android.hardware.camera2.params.DynamicRangeProfiles#HLG10 }</li>
+ * <li>All mandatory stream combinations for this specific capability as per
+ * documentation {@link android.hardware.camera2.CameraDevice#createCaptureSession }</li>
+ * <li>In case the device is not able to capture some combination of supported
* standard 8-bit and/or 10-bit dynamic range profiles within the same capture request,
* then those constraints must be listed in
- * {@link android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints }
- * * Recommended dynamic range profile listed in
- * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE }.</p>
+ * {@link android.hardware.camera2.params.DynamicRangeProfiles#getProfileCaptureRequestConstraints }</li>
+ * <li>Recommended dynamic range profile listed in
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE }.</li>
+ * </ul>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT = 18;
@@ -1224,22 +1228,26 @@
* {@link android.hardware.camera2.params.OutputConfiguration#setStreamUseCase }
* so that the device can optimize camera pipeline parameters such as tuning, sensor
* mode, or ISP settings for a specific user scenario.
- * Some sample usages of this capability are:
- * * Distinguish high quality YUV captures from a regular YUV stream where
- * the image quality may not be as good as the JPEG stream, or
- * * Use one stream to serve multiple purposes: viewfinder, video recording and
+ * Some sample usages of this capability are:</p>
+ * <ul>
+ * <li>Distinguish high quality YUV captures from a regular YUV stream where
+ * the image quality may not be as good as the JPEG stream, or</li>
+ * <li>Use one stream to serve multiple purposes: viewfinder, video recording and
* still capture. This is common with applications that wish to apply edits equally
- * to preview, saved images, and saved videos.</p>
+ * to preview, saved images, and saved videos.</li>
+ * </ul>
* <p>This capability requires the camera device to support the following
- * stream use cases:
- * * DEFAULT for backward compatibility where the application doesn't set
- * a stream use case
- * * PREVIEW for live viewfinder and in-app image analysis
- * * STILL_CAPTURE for still photo capture
- * * VIDEO_RECORD for recording video clips
- * * PREVIEW_VIDEO_STILL for one single stream used for viewfinder, video
- * recording, and still capture.
- * * VIDEO_CALL for long running video calls</p>
+ * stream use cases:</p>
+ * <ul>
+ * <li>DEFAULT for backward compatibility where the application doesn't set
+ * a stream use case</li>
+ * <li>PREVIEW for live viewfinder and in-app image analysis</li>
+ * <li>STILL_CAPTURE for still photo capture</li>
+ * <li>VIDEO_RECORD for recording video clips</li>
+ * <li>PREVIEW_VIDEO_STILL for one single stream used for viewfinder, video
+ * recording, and still capture.</li>
+ * <li>VIDEO_CALL for long running video calls</li>
+ * </ul>
* <p>{@link android.hardware.camera2.CameraCharacteristics#SCALER_AVAILABLE_STREAM_USE_CASES }
* lists all of the supported stream use cases.</p>
* <p>Refer to {@link android.hardware.camera2.CameraDevice#createCaptureSession } for the
@@ -1391,10 +1399,10 @@
* <p>Live stream shown to the user.</p>
* <p>Optimized for performance and usability as a viewfinder, but not necessarily for
* image quality. The output is not meant to be persisted as saved images or video.</p>
- * <p>No stall if android.control.<em> are set to FAST; may have stall if android.control.</em>
- * are set to HIGH_QUALITY. This use case has the same behavior as the default
- * SurfaceView and SurfaceTexture targets. Additionally, this use case can be used for
- * in-app image analysis.</p>
+ * <p>No stall if android.control.* are set to FAST. There may be stall if
+ * they are set to HIGH_QUALITY. This use case has the same behavior as the
+ * default SurfaceView and SurfaceTexture targets. Additionally, this use case can be
+ * used for in-app image analysis.</p>
* @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_USE_CASES
*/
public static final int SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1;
@@ -1441,7 +1449,7 @@
public static final int SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4;
/**
- * <p>Long-running video call optimized for both power efficienty and video quality.</p>
+ * <p>Long-running video call optimized for both power efficiency and video quality.</p>
* <p>The camera sensor may run in a lower-resolution mode to reduce power consumption
* at the cost of some image and digital zoom quality. Unlike VIDEO_RECORD, VIDEO_CALL
* outputs are expected to work in dark conditions, so are usually accompanied with
@@ -2946,10 +2954,10 @@
* android.control.availableHighSpeedVideoConfigurations.</li>
* <li>No processed non-stalling or raw streams are configured.</li>
* </ul>
- * <p>When above conditions are NOT satistied, the controls of this mode and
+ * <p>When above conditions are NOT satisfied, the controls of this mode and
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} will be ignored by the camera device,
* the camera device will fall back to {@link CaptureRequest#CONTROL_MODE android.control.mode} <code>==</code> AUTO,
- * and the returned capture result metadata will give the fps range choosen
+ * and the returned capture result metadata will give the fps range chosen
* by the camera device.</p>
* <p>Switching into or out of this mode may trigger some camera ISP/sensor
* reconfigurations, which may introduce extra latency. It is recommended that
@@ -3034,7 +3042,7 @@
* if the {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} gives range of [100, 1600],
* the camera device auto-exposure routine tuning process may limit the actual
* exposure sensitivity range to [100, 1200] to ensure that the noise level isn't
- * exessive in order to preserve the image quality. Under this situation, the image under
+ * excessive in order to preserve the image quality. Under this situation, the image under
* low light may be under-exposed when the sensor max exposure time (bounded by the
* {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of the
* ON_* modes) and effective max sensitivity are reached. This scene mode allows the
@@ -3631,7 +3639,7 @@
public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
/**
- * <p>Use the gamma value specified in {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma} to peform
+ * <p>Use the gamma value specified in {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma} to perform
* tonemapping.</p>
* <p>All color enhancement and tonemapping must be disabled, except
* for applying the tonemapping curve specified by {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma}.</p>
@@ -3644,7 +3652,7 @@
/**
* <p>Use the preset tonemapping curve specified in
- * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve} to peform tonemapping.</p>
+ * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve} to perform tonemapping.</p>
* <p>All color enhancement and tonemapping must be disabled, except
* for applying the tonemapping curve specified by
* {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve}.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 15e59e0..c5cf0f6 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1767,7 +1767,7 @@
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}. Note that when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}
- * is OFF, the behavior of AWB is device dependent. It is recommened to
+ * is OFF, the behavior of AWB is device dependent. It is recommended to
* also set AWB mode to OFF or lock AWB by using {@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} before
* setting AE mode to OFF.</p>
* <p>When set to the OFF mode, the camera device's auto-white balance
@@ -1917,13 +1917,15 @@
* strategy.</p>
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
- * <p>All intents are supported by all devices, except that:
- * * ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * PRIVATE_REPROCESSING or YUV_REPROCESSING.
- * * MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * MANUAL_SENSOR.
- * * MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * MOTION_TRACKING.</p>
+ * <p>All intents are supported by all devices, except that:</p>
+ * <ul>
+ * <li>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * PRIVATE_REPROCESSING or YUV_REPROCESSING.</li>
+ * <li>MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * MANUAL_SENSOR.</li>
+ * <li>MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * MOTION_TRACKING.</li>
+ * </ul>
* <p><b>Possible values:</b></p>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2680,7 +2682,7 @@
* and keep jpeg and thumbnail image data unrotated.</li>
* <li>Rotate the jpeg and thumbnail image data and not set
* {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
- * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * case, LIMITED or FULL hardware level devices will report rotated thumbnail size in
* capture result, so the width and height will be interchanged if 90 or 270 degree
* orientation is requested. LEGACY device will always report unrotated thumbnail
* size.</li>
@@ -3806,9 +3808,11 @@
/**
* <p>Tonemapping curve to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* GAMMA_VALUE</p>
- * <p>The tonemap curve will be defined the following formula:
- * * OUT = pow(IN, 1.0 / gamma)
- * where IN and OUT is the input pixel value scaled to range [0.0, 1.0],
+ * <p>The tonemap curve will be defined the following formula:</p>
+ * <ul>
+ * <li>OUT = pow(IN, 1.0 / gamma)</li>
+ * </ul>
+ * <p>where IN and OUT is the input pixel value scaled to range [0.0, 1.0],
* pow is the power function and gamma is the gamma value specified by this
* key.</p>
* <p>The same curve will be applied to all color channels. The camera device
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 1faec5b..3e1deb2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1173,7 +1173,7 @@
* <td align="center">Any state (excluding LOCKED)</td>
* <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is CANCEL, converged</td>
* <td align="center">CONVERGED</td>
- * <td align="center">Converged after a precapture sequenceis canceled, transient states are skipped by camera device.</td>
+ * <td align="center">Converged after a precapture sequences canceled, transient states are skipped by camera device.</td>
* </tr>
* <tr>
* <td align="center">CONVERGED</td>
@@ -1847,7 +1847,7 @@
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}. Note that when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}
- * is OFF, the behavior of AWB is device dependent. It is recommened to
+ * is OFF, the behavior of AWB is device dependent. It is recommended to
* also set AWB mode to OFF or lock AWB by using {@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} before
* setting AE mode to OFF.</p>
* <p>When set to the OFF mode, the camera device's auto-white balance
@@ -1997,13 +1997,15 @@
* strategy.</p>
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
- * <p>All intents are supported by all devices, except that:
- * * ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * PRIVATE_REPROCESSING or YUV_REPROCESSING.
- * * MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * MANUAL_SENSOR.
- * * MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
- * MOTION_TRACKING.</p>
+ * <p>All intents are supported by all devices, except that:</p>
+ * <ul>
+ * <li>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * PRIVATE_REPROCESSING or YUV_REPROCESSING.</li>
+ * <li>MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * MANUAL_SENSOR.</li>
+ * <li>MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
+ * MOTION_TRACKING.</li>
+ * </ul>
* <p><b>Possible values:</b></p>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2929,7 +2931,7 @@
* and keep jpeg and thumbnail image data unrotated.</li>
* <li>Rotate the jpeg and thumbnail image data and not set
* {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
- * case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+ * case, LIMITED or FULL hardware level devices will report rotated thumbnail size in
* capture result, so the width and height will be interchanged if 90 or 270 degree
* orientation is requested. LEGACY device will always report unrotated thumbnail
* size.</li>
@@ -3149,7 +3151,7 @@
* <p>When the state is STATIONARY, the lens parameters are not changing. This could be
* either because the parameters are all fixed, or because the lens has had enough
* time to reach the most recently-requested values.
- * If all these lens parameters are not changable for a camera device, as listed below:</p>
+ * If all these lens parameters are not changeable for a camera device, as listed below:</p>
* <ul>
* <li>Fixed focus (<code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} == 0</code>), which means
* {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} parameter will always be 0.</li>
@@ -4009,7 +4011,7 @@
* noise model used here is:</p>
* <p>N(x) = sqrt(Sx + O)</p>
* <p>Where x represents the recorded signal of a CFA channel normalized to
- * the range [0, 1], and S and O are the noise model coeffiecients for
+ * the range [0, 1], and S and O are the noise model coefficients for
* that channel.</p>
* <p>A more detailed description of the noise model can be found in the
* Adobe DNG specification for the NoiseProfile tag.</p>
@@ -4054,7 +4056,7 @@
* <li>1.20 <= R >= 1.03 will require some software
* correction to avoid demosaic errors (3-20% divergence).</li>
* <li>R > 1.20 will require strong software correction to produce
- * a usuable image (>20% divergence).</li>
+ * a usable image (>20% divergence).</li>
* </ul>
* <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
* the camera device has RAW capability.</p>
@@ -4274,7 +4276,7 @@
/**
* <p>Whether <code>RAW</code> images requested have their bayer pattern as described by
* {@link CameraCharacteristics#SENSOR_INFO_BINNING_FACTOR android.sensor.info.binningFactor}.</p>
- * <p>This key will only be present in devices advertisting the
+ * <p>This key will only be present in devices advertising the
* {@link android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR }
* capability which also advertise <code>REMOSAIC_REPROCESSING</code> capability. On all other devices
* RAW targets will have a regular bayer pattern.</p>
@@ -5128,9 +5130,11 @@
/**
* <p>Tonemapping curve to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
* GAMMA_VALUE</p>
- * <p>The tonemap curve will be defined the following formula:
- * * OUT = pow(IN, 1.0 / gamma)
- * where IN and OUT is the input pixel value scaled to range [0.0, 1.0],
+ * <p>The tonemap curve will be defined the following formula:</p>
+ * <ul>
+ * <li>OUT = pow(IN, 1.0 / gamma)</li>
+ * </ul>
+ * <p>where IN and OUT is the input pixel value scaled to range [0.0, 1.0],
* pow is the power function and gamma is the gamma value specified by this
* key.</p>
* <p>The same curve will be applied to all color channels. The camera device
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 1263da6..4d0ba63 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -72,7 +72,7 @@
import java.util.concurrent.Executor;
public final class CameraExtensionSessionImpl extends CameraExtensionSession {
- private static final int PREVIEW_QUEUE_SIZE = 3;
+ private static final int PREVIEW_QUEUE_SIZE = 10;
private static final String TAG = "CameraExtensionSessionImpl";
private final Executor mExecutor;
@@ -1057,15 +1057,8 @@
mClientRequest));
if (mCaptureResultHandler != null) {
- CameraMetadataNative captureResults = new CameraMetadataNative();
- for (CaptureResult.Key key : mSupportedResultKeys) {
- Object value = result.get(key);
- if (value != null) {
- captureResults.set(key, value);
- }
- }
mCaptureResultHandler.onCaptureCompleted(timestamp,
- captureResults);
+ initializeFilteredResults(result));
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1127,6 +1120,11 @@
private class ImageCallback implements OnImageAvailableListener {
@Override
+ public void onImageDropped(long timestamp) {
+ notifyCaptureFailed();
+ }
+
+ @Override
public void onImageAvailable(ImageReader reader, Image img) {
if (mCaptureFailed) {
img.close();
@@ -1160,6 +1158,9 @@
private class ImageLoopbackCallback implements OnImageAvailableListener {
@Override
+ public void onImageDropped(long timestamp) { }
+
+ @Override
public void onImageAvailable(ImageReader reader, Image img) {
img.close();
}
@@ -1221,7 +1222,8 @@
}
private interface OnImageAvailableListener {
- public void onImageAvailable (ImageReader reader, Image img);
+ void onImageDropped(long timestamp);
+ void onImageAvailable (ImageReader reader, Image img);
}
private class CameraOutputImageCallback implements ImageReader.OnImageAvailableListener,
@@ -1263,6 +1265,29 @@
} else {
mImageListenerMap.put(img.getTimestamp(), new Pair<>(img, null));
}
+
+ notifyDroppedImages(timestamp);
+ }
+
+ private void notifyDroppedImages(long timestamp) {
+ Set<Long> timestamps = mImageListenerMap.keySet();
+ ArrayList<Long> removedTs = new ArrayList<>();
+ for (long ts : timestamps) {
+ if (ts < timestamp) {
+ Log.e(TAG, "Dropped image with ts: " + ts);
+ Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(ts);
+ if (entry.second != null) {
+ entry.second.onImageDropped(ts);
+ }
+ if (entry.first != null) {
+ entry.first.close();
+ }
+ removedTs.add(ts);
+ }
+ }
+ for (long ts : removedTs) {
+ mImageListenerMap.remove(ts);
+ }
}
public void registerListener(Long timestamp, OnImageAvailableListener listener) {
@@ -1291,6 +1316,12 @@
entry.first.close();
}
}
+ for (long timestamp : mImageListenerMap.keySet()) {
+ Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(timestamp);
+ if (entry.second != null) {
+ entry.second.onImageDropped(timestamp);
+ }
+ }
mImageListenerMap.clear();
}
}
@@ -1447,7 +1478,6 @@
} else {
notifyConfigurationFailure();
}
-
}
@Override
@@ -1536,7 +1566,16 @@
} else if (mPreviewProcessorType ==
IPreviewExtenderImpl.PROCESSOR_TYPE_IMAGE_PROCESSOR) {
int idx = mPendingResultMap.indexOfKey(timestamp);
- if (idx >= 0) {
+
+ if ((idx >= 0) && (mPendingResultMap.get(timestamp).first == null)) {
+ // Image was dropped before we can receive the capture results
+ if ((mCaptureResultHandler != null)) {
+ mCaptureResultHandler.onCaptureCompleted(timestamp,
+ initializeFilteredResults(result));
+ }
+ discardPendingRepeatingResults(idx, mPendingResultMap, false);
+ } else if (idx >= 0) {
+ // Image came before the capture results
ParcelImage parcelImage = initializeParcelImage(
mPendingResultMap.get(timestamp).first);
try {
@@ -1563,6 +1602,7 @@
}
discardPendingRepeatingResults(idx, mPendingResultMap, false);
} else {
+ // Image not yet available
notifyClient = false;
mPendingResultMap.put(timestamp,
new Pair<>(null,
@@ -1581,16 +1621,8 @@
mClientRequest));
if ((mCaptureResultHandler != null) && (mPreviewProcessorType !=
IPreviewExtenderImpl.PROCESSOR_TYPE_IMAGE_PROCESSOR)) {
- CameraMetadataNative captureResults =
- new CameraMetadataNative();
- for (CaptureResult.Key key : mSupportedResultKeys) {
- Object value = result.get(key);
- if (value != null) {
- captureResults.set(key, value);
- }
- }
mCaptureResultHandler.onCaptureCompleted(timestamp,
- captureResults);
+ initializeFilteredResults(result));
}
} else {
mExecutor.execute(
@@ -1657,19 +1689,24 @@
for (int i = idx; i >= 0; i--) {
if (previewMap.valueAt(i).first != null) {
previewMap.valueAt(i).first.close();
- } else {
- if (mClientNotificationsEnabled && ((i != idx) || notifyCurrentIndex)) {
- Log.w(TAG, "Preview frame drop with timestamp: " + previewMap.keyAt(i));
- final long ident = Binder.clearCallingIdentity();
- try {
- mExecutor.execute(
- () -> mCallbacks
- .onCaptureFailed(CameraExtensionSessionImpl.this,
- mClientRequest));
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ } else if (mClientNotificationsEnabled && (previewMap.valueAt(i).second != null) &&
+ ((i != idx) || notifyCurrentIndex)) {
+ TotalCaptureResult result = previewMap.valueAt(i).second;
+ Long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+ mCaptureResultHandler.onCaptureCompleted(timestamp,
+ initializeFilteredResults(result));
+
+ Log.w(TAG, "Preview frame drop with timestamp: " + previewMap.keyAt(i));
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(
+ () -> mCallbacks
+ .onCaptureFailed(CameraExtensionSessionImpl.this,
+ mClientRequest));
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
+
}
previewMap.removeAt(i);
}
@@ -1683,6 +1720,12 @@
}
@Override
+ public void onImageDropped(long timestamp) {
+ discardPendingRepeatingResults(mPendingResultMap.indexOfKey(timestamp),
+ mPendingResultMap, true);
+ }
+
+ @Override
public void onImageAvailable(ImageReader reader, Image img) {
if (img == null) {
Log.e(TAG, "Invalid image!");
@@ -1703,6 +1746,15 @@
private class ImageProcessCallback implements OnImageAvailableListener {
@Override
+ public void onImageDropped(long timestamp) {
+ discardPendingRepeatingResults(mPendingResultMap.indexOfKey(timestamp),
+ mPendingResultMap, true);
+ // Add an empty frame&results entry to flag that we dropped a frame
+ // and valid capture results can immediately return to client.
+ mPendingResultMap.put(timestamp, new Pair<>(null, null));
+ }
+
+ @Override
public void onImageAvailable(ImageReader reader, Image img) {
if (mPendingResultMap.size() + 1 >= PREVIEW_QUEUE_SIZE) {
// We reached the maximum acquired images limit. This is possible in case we
@@ -1768,6 +1820,17 @@
}
}
+ private CameraMetadataNative initializeFilteredResults(TotalCaptureResult result) {
+ CameraMetadataNative captureResults = new CameraMetadataNative();
+ for (CaptureResult.Key key : mSupportedResultKeys) {
+ Object value = result.get(key);
+ if (value != null) {
+ captureResults.set(key, value);
+ }
+ }
+ return captureResults;
+ }
+
private static Size findSmallestAspectMatchedSize(@NonNull List<Size> sizes,
@NonNull Size arSize) {
final float TOLL = .01f;
diff --git a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
index 14ed689..34c8336 100644
--- a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
+++ b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
@@ -277,7 +277,7 @@
* profile.</p>
*
* @return non-modifiable set of dynamic range profiles
- * @throws IllegalArgumentException - If the profile argument is not
+ * @throws IllegalArgumentException If the profile argument is not
* within the list returned by
* getSupportedProfiles()
*
@@ -303,7 +303,7 @@
*
* @return true if the given profile is not suitable for latency sensitive use cases, false
* otherwise
- * @throws IllegalArgumentException - If the profile argument is not
+ * @throws IllegalArgumentException If the profile argument is not
* within the list returned by
* getSupportedProfiles()
*
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index c341731..062b68e 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -1436,13 +1436,5 @@
* @hide
*/
String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
-
- /**
- * Whether to allow the creation of always unlocked virtual displays by apps having the
- * required permissions.
- * @hide
- */
- String KEY_ALLOW_ALWAYS_UNLOCKED_VIRTUAL_DISPLAYS =
- "allow_always_unlocked_virtual_displays";
}
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
index 4bf9a74..f701ec3 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
@@ -39,6 +39,7 @@
* See {@link FingerprintSensorProperties.SensorType}.
*/
public final @FingerprintSensorProperties.SensorType int sensorType;
+ public final boolean halControlsIllumination;
private final List<SensorLocationInternal> mSensorLocations;
@@ -46,6 +47,7 @@
@SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
@NonNull List<ComponentInfoInternal> componentInfo,
@FingerprintSensorProperties.SensorType int sensorType,
+ boolean halControlsIllumination,
boolean resetLockoutRequiresHardwareAuthToken,
@NonNull List<SensorLocationInternal> sensorLocations) {
// IBiometricsFingerprint@2.1 handles lockout in the framework, so the challenge is not
@@ -55,6 +57,7 @@
super(sensorId, strength, maxEnrollmentsPerUser, componentInfo,
resetLockoutRequiresHardwareAuthToken, false /* resetLockoutRequiresChallenge */);
this.sensorType = sensorType;
+ this.halControlsIllumination = halControlsIllumination;
this.mSensorLocations = List.copyOf(sensorLocations);
}
@@ -68,14 +71,15 @@
boolean resetLockoutRequiresHardwareAuthToken) {
// TODO(b/179175438): Value should be provided from the HAL
this(sensorId, strength, maxEnrollmentsPerUser, componentInfo, sensorType,
- resetLockoutRequiresHardwareAuthToken, List.of(new SensorLocationInternal(
- "" /* displayId */, 540 /* sensorLocationX */, 1636 /* sensorLocationY */,
- 130 /* sensorRadius */)));
+ false /* halControlsIllumination */, resetLockoutRequiresHardwareAuthToken,
+ List.of(new SensorLocationInternal("" /* displayId */, 540 /* sensorLocationX */,
+ 1636 /* sensorLocationY */, 130 /* sensorRadius */)));
}
protected FingerprintSensorPropertiesInternal(Parcel in) {
super(in);
sensorType = in.readInt();
+ halControlsIllumination = in.readBoolean();
mSensorLocations = in.createTypedArrayList(SensorLocationInternal.CREATOR);
}
@@ -101,6 +105,7 @@
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(sensorType);
+ dest.writeBoolean(halControlsIllumination);
dest.writeTypedList(mSensorLocations);
}
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index b37c27c..fc6bc55 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -75,8 +75,15 @@
/**
* Sets the display id that the MouseCursorController will be forced to target. Pass
* {@link android.view.Display#INVALID_DISPLAY} to clear the override.
+ *
+ * Note: This method generally blocks until the pointer display override has propagated.
+ * When setting a new override, the caller should ensure that an input device that can control
+ * the mouse pointer is connected. If a new override is set when no such input device is
+ * connected, the caller may be blocked for an arbitrary period of time.
+ *
+ * @return true if the pointer displayId was set successfully, or false if it fails.
*/
- public abstract void setVirtualMousePointerDisplayId(int pointerDisplayId);
+ public abstract boolean setVirtualMousePointerDisplayId(int pointerDisplayId);
/**
* Gets the display id that the MouseCursorController is being forced to target. Returns
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index f9ed0e3d..3f49b73 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -37,6 +37,7 @@
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodSession;
import android.view.inputmethod.InputMethodSubtype;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.CancellationGroup;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
@@ -194,7 +195,9 @@
case DO_START_INPUT: {
final SomeArgs args = (SomeArgs) msg.obj;
final IBinder startInputToken = (IBinder) args.arg1;
- final IInputContext inputContext = (IInputContext) args.arg2;
+ final IInputContext inputContext = (IInputContext) ((SomeArgs) args.arg2).arg1;
+ final ImeOnBackInvokedDispatcher imeDispatcher =
+ (ImeOnBackInvokedDispatcher) ((SomeArgs) args.arg2).arg2;
final EditorInfo info = (EditorInfo) args.arg3;
final CancellationGroup cancellationGroup = (CancellationGroup) args.arg4;
final boolean restarting = args.argi5 == 1;
@@ -205,7 +208,7 @@
: null;
info.makeCompatible(mTargetSdkVersion);
inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken,
- navButtonFlags);
+ navButtonFlags, imeDispatcher);
args.recycle();
return;
}
@@ -348,13 +351,17 @@
@Override
public void startInput(IBinder startInputToken, IInputContext inputContext,
EditorInfo attribute, boolean restarting,
- @InputMethodNavButtonFlags int navButtonFlags) {
+ @InputMethodNavButtonFlags int navButtonFlags,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (mCancellationGroup == null) {
Log.e(TAG, "startInput must be called after bindInput.");
mCancellationGroup = new CancellationGroup();
}
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = inputContext;
+ args.arg2 = imeDispatcher;
mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOII(DO_START_INPUT, startInputToken,
- inputContext, attribute, mCancellationGroup, restarting ? 1 : 0, navButtonFlags));
+ args, attribute, mCancellationGroup, restarting ? 1 : 0, navButtonFlags));
}
@BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index efd4f06..25296bc 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -101,6 +101,7 @@
import android.view.Choreographer;
import android.view.Gravity;
import android.view.InputChannel;
+import android.view.InputDevice;
import android.view.InputEventReceiver;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -134,6 +135,9 @@
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
+import android.window.ImeOnBackInvokedDispatcher;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import android.window.WindowMetricsHelper;
import com.android.internal.annotations.GuardedBy;
@@ -344,6 +348,9 @@
* A circular buffer of size MAX_EVENTS_BUFFER in case IME is taking too long to add ink view.
**/
private RingBuffer<MotionEvent> mPendingEvents;
+ private ImeOnBackInvokedDispatcher mImeDispatcher;
+ private Boolean mBackCallbackRegistered = false;
+ private final OnBackInvokedCallback mCompatBackCallback = this::compatHandleBack;
/**
* Returns whether {@link InputMethodService} is responsible for rendering the back button and
@@ -797,7 +804,13 @@
@Override
public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
- @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
+ @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
+ mImeDispatcher = imeDispatcher;
+ if (mWindow != null) {
+ mWindow.getOnBackInvokedDispatcher().setImeOnBackInvokedDispatcher(
+ imeDispatcher);
+ }
mPrivOps.reportStartInputAsync(startInputToken);
mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
if (restarting) {
@@ -1496,6 +1509,10 @@
Context.LAYOUT_INFLATER_SERVICE);
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initSoftInputWindow");
mWindow = new SoftInputWindow(this, mTheme, mDispatcherState);
+ if (mImeDispatcher != null) {
+ mWindow.getOnBackInvokedDispatcher()
+ .setImeOnBackInvokedDispatcher(mImeDispatcher);
+ }
mNavigationBarController.onSoftInputWindowCreated(mWindow);
{
final Window window = mWindow.getWindow();
@@ -1608,6 +1625,8 @@
// when IME developers are doing something unsupported.
InputMethodPrivilegedOperationsRegistry.remove(mToken);
}
+ unregisterCompatOnBackInvokedCallback();
+ mImeDispatcher = null;
}
/**
@@ -2568,9 +2587,47 @@
cancelImeSurfaceRemoval();
mInShowWindow = false;
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ registerCompatOnBackInvokedCallback();
}
+ /**
+ * Registers an {@link OnBackInvokedCallback} to handle back invocation when ahead-of-time
+ * back dispatching is enabled. We keep the {@link KeyEvent#KEYCODE_BACK} based legacy code
+ * around to handle back on older devices.
+ */
+ private void registerCompatOnBackInvokedCallback() {
+ if (mBackCallbackRegistered) {
+ return;
+ }
+ if (mWindow != null) {
+ mWindow.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCompatBackCallback);
+ mBackCallbackRegistered = true;
+ }
+ }
+
+ private void unregisterCompatOnBackInvokedCallback() {
+ if (!mBackCallbackRegistered) {
+ return;
+ }
+ if (mWindow != null) {
+ mWindow.getOnBackInvokedDispatcher()
+ .unregisterOnBackInvokedCallback(mCompatBackCallback);
+ mBackCallbackRegistered = false;
+ }
+ }
+
+ private KeyEvent createBackKeyEvent(int action, boolean isTracking) {
+ final long when = SystemClock.uptimeMillis();
+ return new KeyEvent(when, when, action,
+ KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
+ | (isTracking ? KeyEvent.FLAG_TRACKING : 0),
+ InputDevice.SOURCE_KEYBOARD);
+ }
+
private boolean prepareWindow(boolean showInput) {
boolean doShowInput = false;
mDecorViewVisible = true;
@@ -2658,6 +2715,7 @@
}
mLastWasInFullscreenMode = mIsFullscreen;
updateFullscreenMode();
+ unregisterCompatOnBackInvokedCallback();
}
/**
@@ -3797,4 +3855,14 @@
proto.end(token);
}
};
+
+ private void compatHandleBack() {
+ final KeyEvent downEvent = createBackKeyEvent(
+ KeyEvent.ACTION_DOWN, false /* isTracking */);
+ onKeyDown(KeyEvent.KEYCODE_BACK, downEvent);
+ final boolean hasStartedTracking =
+ (downEvent.getFlags() & KeyEvent.FLAG_START_TRACKING) != 0;
+ final KeyEvent upEvent = createBackKeyEvent(KeyEvent.ACTION_UP, hasStartedTracking);
+ onKeyUp(KeyEvent.KEYCODE_BACK, upEvent);
+ }
}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index ecdc803..022d213 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -1361,6 +1361,18 @@
return false;
}
+ // Apps with PROPERTY_NO_APP_DATA_STORAGE should not be allowed in scoped storage
+ final String packageName = AppGlobals.getInitialPackage();
+ try {
+ final PackageManager.Property noAppStorageProp = packageManager.getProperty(
+ PackageManager.PROPERTY_NO_APP_DATA_STORAGE, packageName);
+ if (noAppStorageProp != null && noAppStorageProp.getBoolean()) {
+ return false;
+ }
+ } catch (PackageManager.NameNotFoundException ignore) {
+ // Property not defined for the package
+ }
+
boolean defaultScopedStorage = Compatibility.isChangeEnabled(DEFAULT_SCOPED_STORAGE);
boolean forceEnableScopedStorage = Compatibility.isChangeEnabled(
FORCE_ENABLE_SCOPED_STORAGE);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a64e63e..196f2f9 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2179,7 +2179,10 @@
}
} else {
UserInfo userInfo = getUserInfo(mUserId);
- return userInfo == null ? "" : userInfo.name;
+ if (userInfo != null && userInfo.name != null) {
+ return userInfo.name;
+ }
+ return "";
}
}
diff --git a/core/java/android/os/logcat/ILogcatManagerService.aidl b/core/java/android/os/logcat/ILogcatManagerService.aidl
index 29b4570..67a930a 100644
--- a/core/java/android/os/logcat/ILogcatManagerService.aidl
+++ b/core/java/android/os/logcat/ILogcatManagerService.aidl
@@ -42,31 +42,4 @@
* @param fd The FD (Socket) of client who makes the request.
*/
void finishThread(in int uid, in int gid, in int pid, in int fd);
-
-
- /**
- * The function is called by UX component to notify
- * LogcatManagerService that the user approved
- * the privileged log data access.
- *
- * @param uid The UID of client who makes the request.
- * @param gid The GID of client who makes the request.
- * @param pid The PID of client who makes the request.
- * @param fd The FD (Socket) of client who makes the request.
- */
- void approve(in int uid, in int gid, in int pid, in int fd);
-
-
- /**
- * The function is called by UX component to notify
- * LogcatManagerService that the user declined
- * the privileged log data access.
- *
- * @param uid The UID of client who makes the request.
- * @param gid The GID of client who makes the request.
- * @param pid The PID of client who makes the request.
- * @param fd The FD (Socket) of client who makes the request.
- */
- void decline(in int uid, in int gid, in int pid, in int fd);
}
-
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 69a09fb..0a6a405 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -68,9 +68,18 @@
void onMuted(boolean muted, boolean zenMuted);
/**
* Callback reporting that the seek bar is start tracking.
+ *
* @param sbv - The seek bar that start tracking
*/
void onStartTrackingTouch(SeekBarVolumizer sbv);
+
+ /**
+ * Callback reporting that the seek bar is stop tracking.
+ *
+ * @param sbv - The seek bar that stop tracking
+ */
+ default void onStopTrackingTouch(SeekBarVolumizer sbv) {
+ }
}
private static final int MSG_GROUP_VOLUME_CHANGED = 1;
@@ -451,6 +460,9 @@
public void onStopTrackingTouch(SeekBar seekBar) {
postStartSample();
+ if (mCallback != null) {
+ mCallback.onStopTrackingTouch(this);
+ }
}
public boolean isSamplePlaying() {
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 0e5a65c..77c0067 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -1292,7 +1292,8 @@
USER_MISSED_LOW_RING_VOLUME,
USER_MISSED_NO_VIBRATE,
USER_MISSED_CALL_SCREENING_SERVICE_SILENCED,
- USER_MISSED_CALL_FILTERS_TIMEOUT
+ USER_MISSED_CALL_FILTERS_TIMEOUT,
+ USER_MISSED_NEVER_RANG
})
@Retention(RetentionPolicy.SOURCE)
public @interface MissedReason {}
@@ -1383,6 +1384,13 @@
public static final long USER_MISSED_CALL_FILTERS_TIMEOUT = 1 << 22;
/**
+ * When {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE}, set this bit when
+ * the call ended before ringing.
+ * @hide
+ */
+ public static final long USER_MISSED_NEVER_RANG = 1 << 23;
+
+ /**
* Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#MISSED_TYPE},
* indicates factors which may have lead the user to miss the call.
* <P>Type: INTEGER</P>
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 37f44e9..9a2f7ba 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -738,6 +738,14 @@
*/
public static final String NAMESPACE_VENDOR_SYSTEM_NATIVE = "vendor_system_native";
+ /**
+ * Namespace for DevicePolicyManager related features.
+ *
+ * @hide
+ */
+ public static final String NAMESPACE_DEVICE_POLICY_MANAGER =
+ "device_policy_manager";
+
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1ef1ac5..d2a86eb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7232,13 +7232,6 @@
*/
public static final String LOCATION_SHOW_SYSTEM_OPS = "locationShowSystemOps";
-
- /**
- * Whether or not an indicator experiment has started.
- * @hide
- */
- public static final String LOCATION_INDICATOR_EXPERIMENT_STARTED =
- "locationIndicatorExperimentStarted";
/**
* A flag containing settings used for biometric weak
* @hide
@@ -9702,6 +9695,40 @@
"active_unlock_on_biometric_fail";
/**
+ * If active unlock triggers on biometric failures, include the following error codes
+ * as a biometric failure. See {@link android.hardware.biometrics.BiometricFaceConstants}.
+ * Error codes should be separated by a pipe. For example: "1|4|5". If active unlock
+ * should never trigger on any face errors, this should be set to an empty string.
+ * A null value will use the system default value (TIMEOUT).
+ * @hide
+ */
+ public static final String ACTIVE_UNLOCK_ON_FACE_ERRORS =
+ "active_unlock_on_face_errors";
+
+ /**
+ * If active unlock triggers on biometric failures, include the following acquired info
+ * as a "biometric failure". See {@link android.hardware.biometrics.BiometricFaceConstants}.
+ * Acquired codes should be separated by a pipe. For example: "1|4|5". If active unlock
+ * should never on trigger on any acquired info messages, this should be
+ * set to an empty string. A null value will use the system default value (none).
+ * @hide
+ */
+ public static final String ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO =
+ "active_unlock_on_face_acquire_info";
+
+ /**
+ * If active unlock triggers on biometric failures, then also request active unlock on
+ * unlock intent when each setting (BiometricType) is the only biometric type enrolled.
+ * Biometric types should be separated by a pipe. For example: "0|3" or "0". If this
+ * setting should be disabled, then this should be set to an empty string. A null value
+ * will use the system default value (0 / None).
+ * 0 = None, 1 = Any face, 2 = Any fingerprint, 3 = Under display fingerprint
+ * @hide
+ */
+ public static final String ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED =
+ "active_unlock_on_unlock_intent_when_biometric_enrolled";
+
+ /**
* Whether the assist gesture should be enabled.
*
* @hide
@@ -10128,15 +10155,6 @@
public static final String NOTIFICATION_DISMISS_RTL = "notification_dismiss_rtl";
/**
- * Whether the app-level notification setting is represented by a manifest permission.
- *
- * @hide
- */
- @Readable
- public static final String NOTIFICATION_PERMISSION_ENABLED =
- "notification_permission_enabled";
-
- /**
* Comma separated list of QS tiles that have been auto-added already.
* @hide
*/
diff --git a/core/java/android/service/quickaccesswallet/TEST_MAPPING b/core/java/android/service/quickaccesswallet/TEST_MAPPING
index 4d97ab6..5d2a3a8 100644
--- a/core/java/android/service/quickaccesswallet/TEST_MAPPING
+++ b/core/java/android/service/quickaccesswallet/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-large": [
{
"name": "CtsQuickAccessWalletTestCases"
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 425dbb9..0ec95c6 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -904,7 +904,6 @@
// based on its default wallpaper color hints.
mShouldDim = dimAmount != 0f || mShouldDimByDefault;
updateSurfaceDimming();
- updateSurface(false, false, true);
}
private void updateSurfaceDimming() {
@@ -941,6 +940,7 @@
} else {
Log.v(TAG, "Setting wallpaper dimming: " + 0);
surfaceControlTransaction.setAlpha(mBbqSurfaceControl, 1.0f).apply();
+ updateSurface(false, false, true);
}
mPreviousWallpaperDimAmount = mWallpaperDimAmount;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 3be4c3ed..24ded93 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -50,12 +50,21 @@
public static final String SETTINGS_ENABLE_SECURITY_HUB = "settings_enable_security_hub";
/** @hide */
public static final String SETTINGS_SUPPORT_LARGE_SCREEN = "settings_support_large_screen";
+
/**
* Support per app's language selection
* @hide
*/
public static final String SETTINGS_APP_LANGUAGE_SELECTION = "settings_app_language_selection";
+ /**
+ * Support locale opt-out and opt-in switch for per app's language.
+ * @hide
+ */
+ public static final String SETTINGS_APP_LOCALE_OPT_IN_ENABLED =
+ "settings_app_locale_opt_in_enabled";
+
+
/** @hide */
public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS =
"settings_enable_monitor_phantom_procs";
@@ -97,6 +106,7 @@
DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true");
DEFAULT_FLAGS.put("settings_search_always_expand", "true");
DEFAULT_FLAGS.put(SETTINGS_APP_LANGUAGE_SELECTION, "true");
+ DEFAULT_FLAGS.put(SETTINGS_APP_LOCALE_OPT_IN_ENABLED, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
@@ -106,6 +116,7 @@
static {
PERSISTENT_FLAGS = new HashSet<>();
PERSISTENT_FLAGS.add(SETTINGS_APP_LANGUAGE_SELECTION);
+ PERSISTENT_FLAGS.add(SETTINGS_APP_LOCALE_OPT_IN_ENABLED);
PERSISTENT_FLAGS.add(SETTINGS_SUPPORT_LARGE_SCREEN);
PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
PERSISTENT_FLAGS.add(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index fd557e7..2e48c2b 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -719,9 +719,14 @@
private void releaseSurfaces(boolean releaseSurfacePackage) {
mSurfaceAlpha = 1f;
-
- synchronized (mSurfaceControlLock) {
+
+ mSurfaceLock.lock();
+ try {
mSurface.destroy();
+ } finally {
+ mSurfaceLock.unlock();
+ }
+ synchronized (mSurfaceControlLock) {
if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy();
mBlastBufferQueue = null;
@@ -770,105 +775,99 @@
Transaction surfaceUpdateTransaction) {
boolean realSizeChanged = false;
- mSurfaceLock.lock();
- try {
- mDrawingStopped = !mVisible;
+ mDrawingStopped = !mVisible;
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "Cur surface: " + mSurface);
+ if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ + "Cur surface: " + mSurface);
- // If we are creating the surface control or the parent surface has not
- // changed, then set relative z. Otherwise allow the parent
- // SurfaceChangedCallback to update the relative z. This is needed so that
- // we do not change the relative z before the server is ready to swap the
- // parent surface.
- if (creating) {
- updateRelativeZ(surfaceUpdateTransaction);
- if (mSurfacePackage != null) {
- reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage);
- }
+ // If we are creating the surface control or the parent surface has not
+ // changed, then set relative z. Otherwise allow the parent
+ // SurfaceChangedCallback to update the relative z. This is needed so that
+ // we do not change the relative z before the server is ready to swap the
+ // parent surface.
+ if (creating) {
+ updateRelativeZ(surfaceUpdateTransaction);
+ if (mSurfacePackage != null) {
+ reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage);
}
- mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
-
- if (mViewVisibility) {
- surfaceUpdateTransaction.show(mSurfaceControl);
- } else {
- surfaceUpdateTransaction.hide(mSurfaceControl);
- }
-
-
-
- updateBackgroundVisibility(surfaceUpdateTransaction);
- updateBackgroundColor(surfaceUpdateTransaction);
- if (mUseAlpha) {
- float alpha = getFixedAlpha();
- surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
- mSurfaceAlpha = alpha;
- }
-
- surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
- if ((sizeChanged || hintChanged) && !creating) {
- setBufferSize(surfaceUpdateTransaction);
- }
- if (sizeChanged || creating || !isHardwareAccelerated()) {
-
- // Set a window crop when creating the surface or changing its size to
- // crop the buffer to the surface size since the buffer producer may
- // use SCALING_MODE_SCALE and submit a larger size than the surface
- // size.
- if (mClipSurfaceToBounds && mClipBounds != null) {
- surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
- } else {
- surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
- mSurfaceHeight);
- }
-
- surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
- mSurfaceHeight);
-
- if (isHardwareAccelerated()) {
- // This will consume the passed in transaction and the transaction will be
- // applied on a render worker thread.
- replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
- } else {
- onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
- mScreenRect.left /*positionLeft*/,
- mScreenRect.top /*positionTop*/,
- mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
- mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
- }
- if (DEBUG_POSITION) {
- Log.d(TAG, String.format(
- "%d performSurfaceTransaction %s "
- + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
- System.identityHashCode(this),
- isHardwareAccelerated() ? "RenderWorker" : "UI Thread",
- mScreenRect.left, mScreenRect.top, mScreenRect.right,
- mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
- }
- }
- applyTransactionOnVriDraw(surfaceUpdateTransaction);
- updateEmbeddedAccessibilityMatrix(false);
-
- mSurfaceFrame.left = 0;
- mSurfaceFrame.top = 0;
- if (translator == null) {
- mSurfaceFrame.right = mSurfaceWidth;
- mSurfaceFrame.bottom = mSurfaceHeight;
- } else {
- float appInvertedScale = translator.applicationInvertedScale;
- mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
- mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
- }
- final int surfaceWidth = mSurfaceFrame.right;
- final int surfaceHeight = mSurfaceFrame.bottom;
- realSizeChanged = mLastSurfaceWidth != surfaceWidth
- || mLastSurfaceHeight != surfaceHeight;
- mLastSurfaceWidth = surfaceWidth;
- mLastSurfaceHeight = surfaceHeight;
- } finally {
- mSurfaceLock.unlock();
}
+ mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
+
+ if (mViewVisibility) {
+ surfaceUpdateTransaction.show(mSurfaceControl);
+ } else {
+ surfaceUpdateTransaction.hide(mSurfaceControl);
+ }
+
+
+
+ updateBackgroundVisibility(surfaceUpdateTransaction);
+ updateBackgroundColor(surfaceUpdateTransaction);
+ if (mUseAlpha) {
+ float alpha = getFixedAlpha();
+ surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
+ mSurfaceAlpha = alpha;
+ }
+
+ surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
+ if ((sizeChanged || hintChanged) && !creating) {
+ setBufferSize(surfaceUpdateTransaction);
+ }
+ if (sizeChanged || creating || !isHardwareAccelerated()) {
+ // Set a window crop when creating the surface or changing its size to
+ // crop the buffer to the surface size since the buffer producer may
+ // use SCALING_MODE_SCALE and submit a larger size than the surface
+ // size.
+ if (mClipSurfaceToBounds && mClipBounds != null) {
+ surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
+ } else {
+ surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
+ mSurfaceHeight);
+ }
+
+ surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
+ mSurfaceHeight);
+
+ if (isHardwareAccelerated()) {
+ // This will consume the passed in transaction and the transaction will be
+ // applied on a render worker thread.
+ replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
+ } else {
+ onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
+ mScreenRect.left /*positionLeft*/,
+ mScreenRect.top /*positionTop*/,
+ mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
+ mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
+ }
+ if (DEBUG_POSITION) {
+ Log.d(TAG, String.format(
+ "%d performSurfaceTransaction %s "
+ + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
+ System.identityHashCode(this),
+ isHardwareAccelerated() ? "RenderWorker" : "UI Thread",
+ mScreenRect.left, mScreenRect.top, mScreenRect.right,
+ mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
+ }
+ }
+ applyTransactionOnVriDraw(surfaceUpdateTransaction);
+ updateEmbeddedAccessibilityMatrix(false);
+ mSurfaceFrame.left = 0;
+ mSurfaceFrame.top = 0;
+ if (translator == null) {
+ mSurfaceFrame.right = mSurfaceWidth;
+ mSurfaceFrame.bottom = mSurfaceHeight;
+ } else {
+ float appInvertedScale = translator.applicationInvertedScale;
+ mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
+ mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
+ }
+ final int surfaceWidth = mSurfaceFrame.right;
+ final int surfaceHeight = mSurfaceFrame.bottom;
+ realSizeChanged = mLastSurfaceWidth != surfaceWidth
+ || mLastSurfaceHeight != surfaceHeight;
+ mLastSurfaceWidth = surfaceWidth;
+ mLastSurfaceHeight = surfaceHeight;
+
return realSizeChanged;
}
@@ -1103,21 +1102,30 @@
* Surface for compatibility reasons.
*/
private void copySurface(boolean surfaceControlCreated, boolean bufferSizeChanged) {
- if (surfaceControlCreated) {
- mSurface.copyFrom(mBlastBufferQueue);
- }
+ // Some legacy applications use the underlying native {@link Surface} object
+ // as a key to whether anything has changed. In these cases, updates to the
+ // existing {@link Surface} will be ignored when the size changes.
+ // Therefore, we must explicitly recreate the {@link Surface} in these
+ // cases.
+ boolean needsWorkaround = bufferSizeChanged &&
+ getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O;
+ if (!surfaceControlCreated && !needsWorkaround) {
+ return;
+ }
+ mSurfaceLock.lock();
+ try {
+ if (surfaceControlCreated) {
+ mSurface.copyFrom(mBlastBufferQueue);
+ }
- if (bufferSizeChanged && getContext().getApplicationInfo().targetSdkVersion
- < Build.VERSION_CODES.O) {
- // Some legacy applications use the underlying native {@link Surface} object
- // as a key to whether anything has changed. In these cases, updates to the
- // existing {@link Surface} will be ignored when the size changes.
- // Therefore, we must explicitly recreate the {@link Surface} in these
- // cases.
- if (mBlastBufferQueue != null) {
- mSurface.transferFrom(mBlastBufferQueue.createSurfaceWithHandle());
- }
- }
+ if (needsWorkaround) {
+ if (mBlastBufferQueue != null) {
+ mSurface.transferFrom(mBlastBufferQueue.createSurfaceWithHandle());
+ }
+ }
+ } finally {
+ mSurfaceLock.unlock();
+ }
}
private void setBufferSize(Transaction transaction) {
@@ -1200,8 +1208,10 @@
}
mTransformHint = viewRoot.getBufferTransformHint();
mBlastSurfaceControl.setTransformHint(mTransformHint);
+
mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
+ mBlastBufferQueue.setTransactionHangCallback(ViewRootImpl.sTransactionHangCallback);
}
private void onDrawFinished() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7691fb4..d04b07c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8206,24 +8206,25 @@
if (canNotifyAutofillEnterExitEvent()) {
AutofillManager afm = getAutofillManager();
if (afm != null) {
- if (enter && isFocused()) {
+ if (enter) {
// We have not been laid out yet, hence cannot evaluate
// whether this view is visible to the user, we will do
// the evaluation once layout is complete.
if (!isLaidOut()) {
mPrivateFlags3 |= PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
} else if (isVisibleToUser()) {
- // TODO This is a potential problem that View gets focus before it's visible
- // to User. Ideally View should handle the event when isVisibleToUser()
- // becomes true where it should issue notifyViewEntered().
- afm.notifyViewEntered(this);
- } else {
- afm.enableFillRequestActivityStarted(this);
+ if (isFocused()) {
+ // TODO This is a potential problem that View gets focus before it's
+ // visible to User. Ideally View should handle the event when
+ // isVisibleToUser() becomes true where it should issue
+ // notifyViewEntered().
+ afm.notifyViewEntered(this);
+ } else {
+ afm.notifyViewEnteredForFillDialog(this);
+ }
}
- } else if (!enter && !isFocused()) {
+ } else if (!isFocused()) {
afm.notifyViewExited(this);
- } else if (enter) {
- afm.enableFillRequestActivityStarted(this);
}
}
}
@@ -9921,7 +9922,7 @@
* <ol>
* <li>It should only be called when content capture is enabled for the view.
* <li>It must call viewAppeared() before viewDisappeared()
- * <li>viewAppearead() can only be called when the view is visible and laidout
+ * <li>viewAppeared() can only be called when the view is visible and laid out
* <li>It should not call the same event twice.
* </ol>
*/
@@ -9998,6 +9999,11 @@
Log.v(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on disappeared for " + this);
}
}
+
+ // We reset any translation state as views may be re-used (e.g., as in ListView and
+ // RecyclerView). We only need to do this for views important for content capture since
+ // views unimportant for content capture won't be translated anyway.
+ clearTranslationState();
}
}
@@ -11752,6 +11758,7 @@
&& (info.mHandwritingArea == null || !isAutoHandwritingEnabled())) {
if (info.mPositionUpdateListener != null) {
mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener);
+ info.mPositionUpdateListener = null;
info.mPositionChangedUpdate = null;
}
} else {
@@ -11863,6 +11870,8 @@
* <p>
* @see #setPreferKeepClear
* @see #getPreferKeepClearRects
+ *
+ * @param rects A list of rects in this view's local coordinate system
*/
public final void setPreferKeepClearRects(@NonNull List<Rect> rects) {
final ListenerInfo info = getListenerInfo();
@@ -11903,6 +11912,8 @@
* @see #setPreferKeepClear
* @see #getPreferKeepClearRects
*
+ * @param rects A list of rects in this view's local coordinate system
+ *
* @hide
*/
@SystemApi
@@ -12713,6 +12724,21 @@
}
/**
+ * @hide
+ */
+ public void clearTranslationState() {
+ if (mViewTranslationCallback != null) {
+ mViewTranslationCallback.onClearTranslation(this);
+ }
+ clearViewTranslationCallback();
+ clearViewTranslationResponse();
+ if (hasTranslationTransientState()) {
+ setHasTransientState(false);
+ setHasTranslationTransientState(false);
+ }
+ }
+
+ /**
* Returns true if this view is currently attached to a window.
*/
public boolean isAttachedToWindow() {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 335cd27..48c102b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -590,7 +590,6 @@
@Nullable
int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED;
boolean mPerformContentCapture;
- boolean mPerformAutoFill;
boolean mReportNextDraw;
@@ -858,6 +857,28 @@
*/
private Bundle mRelayoutBundle = new Bundle();
+ private static volatile boolean sAnrReported = false;
+ static BLASTBufferQueue.TransactionHangCallback sTransactionHangCallback =
+ new BLASTBufferQueue.TransactionHangCallback() {
+ @Override
+ public void onTransactionHang(boolean isGPUHang) {
+ if (isGPUHang && !sAnrReported) {
+ sAnrReported = true;
+ try {
+ ActivityManager.getService().appNotResponding(
+ "Buffer processing hung up due to stuck fence. Indicates GPU hang");
+ } catch (RemoteException e) {
+ // We asked the system to crash us, but the system
+ // already crashed. Unfortunately things may be
+ // out of control.
+ }
+ } else {
+ // TODO: Do something with this later. For now we just ANR
+ // in dequeue buffer later like we always have.
+ }
+ }
+ };
+
private String mTag = TAG;
public ViewRootImpl(Context context, Display display) {
@@ -890,7 +911,6 @@
mPreviousTransparentRegion = new Region();
mFirst = true; // true for the first time the view is added
mPerformContentCapture = true; // also true for the first time the view is added
- mPerformAutoFill = true;
mAdded = false;
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
context);
@@ -2100,6 +2120,7 @@
}
mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format);
+ mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);
Surface blastSurface = mBlastBufferQueue.createSurface();
// Only call transferFrom if the surface has changed to prevent inc the generation ID and
// causing EGL resources to be recreated.
@@ -4196,26 +4217,6 @@
});
}
- @Nullable
- private void registerFrameDrawingCallbackForBlur() {
- if (!isHardwareEnabled()) {
- return;
- }
- final boolean hasBlurUpdates = mBlurRegionAggregator.hasUpdates();
- final boolean needsCallbackForBlur = hasBlurUpdates || mBlurRegionAggregator.hasRegions();
-
- if (!needsCallbackForBlur) {
- return;
- }
-
- final BackgroundBlurDrawable.BlurRegion[] blurRegionsForFrame =
- mBlurRegionAggregator.getBlurRegionsCopyForRT();
-
- // The callback will run on the render thread.
- registerRtFrameCallback((frame) -> mBlurRegionAggregator
- .dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates));
- }
-
private void registerCallbackForPendingTransactions() {
registerRtFrameCallback(new FrameDrawingCallback() {
@Override
@@ -4253,7 +4254,6 @@
mIsDrawing = true;
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
- registerFrameDrawingCallbackForBlur();
addFrameCommitCallbackIfNeeded();
boolean usingAsyncReport = isHardwareEnabled() && mSyncBufferCallback != null;
@@ -4329,18 +4329,6 @@
if (mPerformContentCapture) {
performContentCaptureInitialReport();
}
-
- if (mPerformAutoFill) {
- notifyEnterForAutoFillIfNeeded();
- }
- }
-
- private void notifyEnterForAutoFillIfNeeded() {
- mPerformAutoFill = false;
- final AutofillManager afm = getAutofillManager();
- if (afm != null) {
- afm.notifyViewEnteredForActivityStarted(mView);
- }
}
/**
@@ -6107,6 +6095,28 @@
@Override
protected int onProcess(QueuedInputEvent q) {
+ if (q.mEvent instanceof KeyEvent) {
+ final KeyEvent event = (KeyEvent) q.mEvent;
+
+ // If the new back dispatch is enabled, intercept KEYCODE_BACK before it reaches the
+ // view tree or IME, and invoke the appropriate {@link OnBackInvokedCallback}.
+ if (isBack(event)
+ && mContext != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
+ OnBackInvokedCallback topCallback =
+ getOnBackInvokedDispatcher().getTopCallback();
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (topCallback != null) {
+ topCallback.onBackInvoked();
+ return FINISH_HANDLED;
+ }
+ } else {
+ // Drop other actions such as {@link KeyEvent.ACTION_DOWN}.
+ return FINISH_NOT_HANDLED;
+ }
+ }
+ }
+
if (mInputQueue != null && q.mEvent instanceof KeyEvent) {
mInputQueue.sendInputEvent(q.mEvent, q, true, this);
return DEFER;
@@ -6458,24 +6468,6 @@
return FINISH_HANDLED;
}
- // If the new back dispatch is enabled, intercept KEYCODE_BACK before it reaches the
- // view tree and invoke the appropriate {@link OnBackInvokedCallback}.
- if (isBack(event)
- && mContext != null
- && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
- OnBackInvokedCallback topCallback =
- getOnBackInvokedDispatcher().getTopCallback();
- if (event.getAction() == KeyEvent.ACTION_UP) {
- if (topCallback != null) {
- topCallback.onBackInvoked();
- return FINISH_HANDLED;
- }
- } else {
- // Drop other actions such as {@link KeyEvent.ACTION_DOWN}.
- return FINISH_NOT_HANDLED;
- }
- }
-
// Deliver the key to the view hierarchy.
if (mView.dispatchKeyEvent(event)) {
return FINISH_HANDLED;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 5bc340b..00052f6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3108,10 +3108,14 @@
/**
* The preferred refresh rate for the window.
- *
+ * <p>
* This must be one of the supported refresh rates obtained for the display(s) the window
* is on. The selected refresh rate will be applied to the display's default mode.
- *
+ * <p>
+ * This should be used in favor of {@link LayoutParams#preferredDisplayModeId} for
+ * applications that want to specify the refresh rate, but do not want to specify a
+ * preference for any other displayMode properties (e.g., resolution).
+ * <p>
* This value is ignored if {@link #preferredDisplayModeId} is set.
*
* @see Display#getSupportedRefreshRates()
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 0a75992..dcedb30 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -102,6 +102,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import sun.misc.Cleaner;
@@ -645,16 +646,6 @@
private boolean mEnabledForAugmentedAutofillOnly;
/**
- * Indicates whether there are any fields that need to do a fill request
- * after the activity starts.
- *
- * Note: This field will be set to true multiple times if there are many
- * autofillable views. So needs to check mIsFillRequested at the same time to
- * avoid re-trigger autofill.
- */
- private boolean mRequireAutofill;
-
- /**
* Indicates whether there is already a field to do a fill request after
* the activity started.
*
@@ -663,7 +654,7 @@
* triggered autofill, it is unnecessary to trigger again through
* AutofillManager#notifyViewEnteredForActivityStarted.
*/
- private boolean mIsFillRequested;
+ private AtomicBoolean mIsFillRequested;
@Nullable private List<AutofillId> mFillDialogTriggerIds;
@@ -811,8 +802,7 @@
mContext = Objects.requireNonNull(context, "context cannot be null");
mService = service;
mOptions = context.getAutofillOptions();
- mIsFillRequested = false;
- mRequireAutofill = false;
+ mIsFillRequested = new AtomicBoolean(false);
mIsFillDialogEnabled = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_AUTOFILL,
@@ -1113,22 +1103,31 @@
}
/**
- * The view have the allowed autofill hints, marked to perform a fill request after layout if
- * the field does not trigger a fill request.
+ * The {@link #DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED} is {@code true} or the view have
+ * the allowed autofill hints, performs a fill request to know there is any field supported
+ * fill dialog.
*
* @hide
*/
- public void enableFillRequestActivityStarted(View v) {
- if (mRequireAutofill) {
+ public void notifyViewEnteredForFillDialog(View v) {
+ // Skip if the fill request has been performed for a view.
+ if (mIsFillRequested.get()) {
return;
}
if (mIsFillDialogEnabled
|| ArrayUtils.containsAny(v.getAutofillHints(), mFillDialogEnabledHints)) {
if (sDebug) {
- Log.d(TAG, "Trigger fill request at starting");
+ Log.d(TAG, "Trigger fill request at view entered");
}
- mRequireAutofill = true;
+
+ // Note: No need for atomic getAndSet as this method is called on the UI thread.
+ mIsFillRequested.set(true);
+
+ int flags = FLAG_SUPPORTS_FILL_DIALOG;
+ flags |= FLAG_VIEW_NOT_FOCUSED;
+ // use root view, so autofill UI does not trigger immediately.
+ notifyViewEntered(v.getRootView(), flags);
}
}
@@ -1136,25 +1135,6 @@
return mIsFillDialogEnabled || !ArrayUtils.isEmpty(mFillDialogEnabledHints);
}
- /**
- * Notify autofill to do a fill request while the activity started.
- *
- * @hide
- */
- public void notifyViewEnteredForActivityStarted(@NonNull View view) {
- if (!hasAutofillFeature() || !hasFillDialogUiFeature()) {
- return;
- }
-
- if (!mRequireAutofill || mIsFillRequested) {
- return;
- }
-
- int flags = FLAG_SUPPORTS_FILL_DIALOG;
- flags |= FLAG_VIEW_NOT_FOCUSED;
- notifyViewEntered(view, flags);
- }
-
private int getImeStateFlag(View v) {
final WindowInsets rootWindowInsets = v.getRootWindowInsets();
if (rootWindowInsets != null && rootWindowInsets.isVisible(WindowInsets.Type.ime())) {
@@ -1203,7 +1183,7 @@
}
AutofillCallback callback;
synchronized (mLock) {
- mIsFillRequested = true;
+ mIsFillRequested.set(true);
callback = notifyViewEnteredLocked(view, flags);
}
@@ -2119,8 +2099,7 @@
mFillableIds = null;
mSaveTriggerId = null;
mIdShownFillUi = null;
- mIsFillRequested = false;
- mRequireAutofill = false;
+ mIsFillRequested.set(false);
mShowAutofillDialogCalled = false;
mFillDialogTriggerIds = null;
if (resetEnteredIds) {
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index 6209b46..dbdc0da 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -29,6 +29,7 @@
import android.view.InputChannel;
import android.view.MotionEvent;
import android.view.View;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
@@ -232,6 +233,10 @@
* long as your implementation of {@link InputMethod} relies on such
* IPCs
* @param navButtonFlags {@link InputMethodNavButtonFlags} in the initial state of this session.
+ * @param imeDispatcher The {@link ImeOnBackInvokedDispatcher }} to be set on the
+ * IME's {@link android.window.WindowOnBackInvokedDispatcher}, so that IME
+ * {@link android.window.OnBackInvokedCallback}s can be forwarded to
+ * the client requesting to start input.
* @see #startInput(InputConnection, EditorInfo)
* @see #restartInput(InputConnection, EditorInfo)
* @see EditorInfo
@@ -240,7 +245,8 @@
@MainThread
default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
- @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags) {
+ @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (restarting) {
restartInput(inputConnection, editorInfo);
} else {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index d9bde58..e2e9a85 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -91,6 +91,8 @@
import android.view.ViewRootImpl;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.autofill.AutofillManager;
+import android.window.ImeOnBackInvokedDispatcher;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.DirectBootAwareness;
@@ -105,6 +107,7 @@
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.os.SomeArgs;
+import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
@@ -279,6 +282,21 @@
private static final String SUBTYPE_MODE_VOICE = "voice";
/**
+ * Provide this to {@link IInputMethodManager#startInputOrWindowGainedFocus(
+ * int, IInputMethodClient, IBinder, int, int, int, EditorInfo, IInputContext, int)} to receive
+ * {@link android.window.OnBackInvokedCallback} registrations from IME.
+ */
+ private final ImeOnBackInvokedDispatcher mImeDispatcher =
+ new ImeOnBackInvokedDispatcher(Handler.getMain()) {
+ @Override
+ public WindowOnBackInvokedDispatcher getReceivingDispatcher() {
+ synchronized (mH) {
+ return mCurRootView != null ? mCurRootView.getOnBackInvokedDispatcher() : null;
+ }
+ }
+ };
+
+ /**
* Ensures that {@link #sInstance} becomes non-{@code null} for application that have directly
* or indirectly relied on {@link #sInstance} via reflection or something like that.
*
@@ -740,7 +758,8 @@
windowFlags,
null,
null, null,
- mCurRootView.mContext.getApplicationInfo().targetSdkVersion);
+ mCurRootView.mContext.getApplicationInfo().targetSdkVersion,
+ mImeDispatcher);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1687,6 +1706,8 @@
mServedConnecting = false;
clearConnectionLocked();
}
+ // Clear the back callbacks held by the ime dispatcher to avoid memory leaks.
+ mImeDispatcher.clear();
}
public void displayCompletions(View view, CompletionInfo[] completions) {
@@ -2359,7 +2380,8 @@
softInputMode, windowFlags, tba, servedInputConnection,
servedInputConnection == null ? null
: servedInputConnection.asIRemoteAccessibilityInputConnection(),
- view.getContext().getApplicationInfo().targetSdkVersion);
+ view.getContext().getApplicationInfo().targetSdkVersion,
+ mImeDispatcher);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index 8cf032b..6bf2474 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -158,12 +158,7 @@
case STATE_UI_TRANSLATION_FINISHED:
destroyTranslators();
runForEachView((view, callback) -> {
- callback.onClearTranslation(view);
- view.clearViewTranslationResponse();
- if (view.hasTranslationTransientState()) {
- view.setHasTransientState(false);
- view.setHasTranslationTransientState(false);
- }
+ view.clearTranslationState();
});
notifyTranslationFinished(/* activityDestroyed= */ false);
synchronized (mLock) {
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.aidl b/core/java/android/window/ImeOnBackInvokedDispatcher.aidl
new file mode 100644
index 0000000..04e6420
--- /dev/null
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/os/ParcelFileDescriptor.aidl
+**
+** Copyright 2022, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.window;
+
+parcelable ImeOnBackInvokedDispatcher;
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
new file mode 100644
index 0000000..d5763aa
--- /dev/null
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -0,0 +1,187 @@
+/*
+ * 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.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * A {@link OnBackInvokedDispatcher} for IME that forwards {@link OnBackInvokedCallback}
+ * registrations from the IME process to the app process to be registered on the app window.
+ * <p>
+ * The app process creates and propagates an instance of {@link ImeOnBackInvokedDispatcher}
+ * to the IME to be set on the IME window's {@link WindowOnBackInvokedDispatcher}.
+ * <p>
+ * @see WindowOnBackInvokedDispatcher#setImeOnBackInvokedDispatcher
+ *
+ * @hide
+ */
+public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parcelable {
+
+ private static final String TAG = "ImeBackDispatcher";
+ static final String RESULT_KEY_ID = "id";
+ static final String RESULT_KEY_CALLBACK = "callback";
+ static final String RESULT_KEY_PRIORITY = "priority";
+ static final int RESULT_CODE_REGISTER = 0;
+ static final int RESULT_CODE_UNREGISTER = 1;
+ @NonNull
+ private final ResultReceiver mResultReceiver;
+
+ public ImeOnBackInvokedDispatcher(Handler handler) {
+ mResultReceiver = new ResultReceiver(handler) {
+ @Override
+ public void onReceiveResult(int resultCode, Bundle resultData) {
+ WindowOnBackInvokedDispatcher dispatcher = getReceivingDispatcher();
+ if (dispatcher != null) {
+ receive(resultCode, resultData, dispatcher);
+ }
+ }
+ };
+ }
+
+ /**
+ * Override this method to return the {@link WindowOnBackInvokedDispatcher} of the window
+ * that should receive the forwarded callback.
+ */
+ @Nullable
+ protected WindowOnBackInvokedDispatcher getReceivingDispatcher() {
+ return null;
+ }
+
+ ImeOnBackInvokedDispatcher(Parcel in) {
+ mResultReceiver = in.readTypedObject(ResultReceiver.CREATOR);
+ }
+
+ @Override
+ public void registerOnBackInvokedCallback(
+ @OnBackInvokedDispatcher.Priority int priority,
+ @NonNull OnBackInvokedCallback callback) {
+ final Bundle bundle = new Bundle();
+ final IOnBackInvokedCallback iCallback =
+ new WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper(callback);
+ bundle.putBinder(RESULT_KEY_CALLBACK, iCallback.asBinder());
+ bundle.putInt(RESULT_KEY_PRIORITY, priority);
+ bundle.putInt(RESULT_KEY_ID, callback.hashCode());
+ mResultReceiver.send(RESULT_CODE_REGISTER, bundle);
+ }
+
+ @Override
+ public void unregisterOnBackInvokedCallback(
+ @NonNull OnBackInvokedCallback callback) {
+ Bundle bundle = new Bundle();
+ bundle.putInt(RESULT_KEY_ID, callback.hashCode());
+ mResultReceiver.send(RESULT_CODE_UNREGISTER, bundle);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mResultReceiver, flags);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<ImeOnBackInvokedDispatcher> CREATOR =
+ new Parcelable.Creator<ImeOnBackInvokedDispatcher>() {
+ public ImeOnBackInvokedDispatcher createFromParcel(Parcel in) {
+ return new ImeOnBackInvokedDispatcher(in);
+ }
+ public ImeOnBackInvokedDispatcher[] newArray(int size) {
+ return new ImeOnBackInvokedDispatcher[size];
+ }
+ };
+
+ private final HashMap<Integer, OnBackInvokedCallback> mImeCallbackMap = new HashMap<>();
+
+ private void receive(
+ int resultCode, Bundle resultData,
+ @NonNull OnBackInvokedDispatcher receivingDispatcher) {
+ final int callbackId = resultData.getInt(RESULT_KEY_ID);
+ if (resultCode == RESULT_CODE_REGISTER) {
+ int priority = resultData.getInt(RESULT_KEY_PRIORITY);
+ final IOnBackInvokedCallback callback = IOnBackInvokedCallback.Stub.asInterface(
+ resultData.getBinder(RESULT_KEY_CALLBACK));
+ registerReceivedCallback(
+ callback, priority, callbackId, receivingDispatcher);
+ } else if (resultCode == RESULT_CODE_UNREGISTER) {
+ unregisterReceivedCallback(callbackId, receivingDispatcher);
+ }
+ }
+
+ private void registerReceivedCallback(
+ @NonNull IOnBackInvokedCallback iCallback,
+ @OnBackInvokedDispatcher.Priority int priority,
+ int callbackId,
+ @NonNull OnBackInvokedDispatcher receivingDispatcher) {
+ final ImeOnBackInvokedCallback imeCallback =
+ new ImeOnBackInvokedCallback(iCallback);
+ mImeCallbackMap.put(callbackId, imeCallback);
+ receivingDispatcher.registerOnBackInvokedCallback(priority, imeCallback);
+ }
+
+ private void unregisterReceivedCallback(
+ int callbackId, OnBackInvokedDispatcher receivingDispatcher) {
+ final OnBackInvokedCallback callback = mImeCallbackMap.get(callbackId);
+ if (callback == null) {
+ Log.e(TAG, "Ime callback not found. Ignoring unregisterReceivedCallback. "
+ + "callbackId: " + callbackId);
+ return;
+ }
+ receivingDispatcher.unregisterOnBackInvokedCallback(callback);
+ }
+
+ /** Clears all registered callbacks on the instance. */
+ public void clear() {
+ mImeCallbackMap.clear();
+ }
+
+ static class ImeOnBackInvokedCallback implements OnBackInvokedCallback {
+ @NonNull
+ private final IOnBackInvokedCallback mIOnBackInvokedCallback;
+
+ ImeOnBackInvokedCallback(@NonNull IOnBackInvokedCallback iCallback) {
+ mIOnBackInvokedCallback = iCallback;
+ }
+
+ @Override
+ public void onBackInvoked() {
+ try {
+ if (mIOnBackInvokedCallback != null) {
+ mIOnBackInvokedCallback.onBackInvoked();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
+ }
+ }
+
+ IOnBackInvokedCallback getIOnBackInvokedCallback() {
+ return mIOnBackInvokedCallback;
+ }
+ }
+}
diff --git a/core/java/android/window/OnBackInvokedDispatcher.java b/core/java/android/window/OnBackInvokedDispatcher.java
index 6bc2b50..3539049a 100644
--- a/core/java/android/window/OnBackInvokedDispatcher.java
+++ b/core/java/android/window/OnBackInvokedDispatcher.java
@@ -96,4 +96,19 @@
* @hide
*/
default void registerSystemOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback) { }
+
+
+ /**
+ * Sets an {@link ImeOnBackInvokedDispatcher} to forward {@link OnBackInvokedCallback}s
+ * from IME to the app process to be registered on the app window.
+ *
+ * Only call this on the IME window. Create the {@link ImeOnBackInvokedDispatcher} from
+ * the application process and override
+ * {@link ImeOnBackInvokedDispatcher#getReceivingDispatcher()} to point to the app
+ * window's {@link WindowOnBackInvokedDispatcher}.
+ *
+ * @hide
+ */
+ default void setImeOnBackInvokedDispatcher(
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) { }
}
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index 4409397..bedf503 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -49,6 +49,7 @@
private final List<Pair<OnBackInvokedCallback, Integer>> mCallbacks = new ArrayList<>();
private final Object mLock = new Object();
private OnBackInvokedDispatcher mActualDispatcher = null;
+ private ImeOnBackInvokedDispatcher mImeDispatcher;
@Override
public void registerOnBackInvokedCallback(
@@ -108,6 +109,9 @@
Log.v(TAG, String.format("Proxy transferring %d callbacks to %s", mCallbacks.size(),
mActualDispatcher));
}
+ if (mImeDispatcher != null) {
+ mActualDispatcher.setImeOnBackInvokedDispatcher(mImeDispatcher);
+ }
for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) {
int priority = callbackPair.second;
if (priority >= 0) {
@@ -117,6 +121,7 @@
}
}
mCallbacks.clear();
+ mImeDispatcher = null;
}
private void clearCallbacksOnDispatcher() {
@@ -142,6 +147,7 @@
}
synchronized (mLock) {
mCallbacks.clear();
+ mImeDispatcher = null;
}
}
@@ -169,4 +175,14 @@
transferCallbacksToDispatcher();
}
}
+
+ @Override
+ public void setImeOnBackInvokedDispatcher(
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
+ if (mActualDispatcher != null) {
+ mActualDispatcher.setImeOnBackInvokedDispatcher(imeDispatcher);
+ } else {
+ mImeDispatcher = imeDispatcher;
+ }
+ }
}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 781859c..edfdbcc 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -55,6 +55,8 @@
.getInt("persist.wm.debug.predictive_back", 1) != 0;
private static final boolean ALWAYS_ENFORCE_PREDICTIVE_BACK = SystemProperties
.getInt("persist.wm.debug.predictive_back_always_enforce", 0) != 0;
+ @Nullable
+ private ImeOnBackInvokedDispatcher mImeDispatcher;
/** Convenience hashmap to quickly decide if a callback has been added. */
private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
@@ -94,6 +96,10 @@
private void registerOnBackInvokedCallbackUnchecked(
@NonNull OnBackInvokedCallback callback, @Priority int priority) {
+ if (mImeDispatcher != null) {
+ mImeDispatcher.registerOnBackInvokedCallback(priority, callback);
+ return;
+ }
if (!mOnBackInvokedCallbacks.containsKey(priority)) {
mOnBackInvokedCallbacks.put(priority, new ArrayList<>());
}
@@ -120,6 +126,10 @@
@Override
public void unregisterOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback) {
+ if (mImeDispatcher != null) {
+ mImeDispatcher.unregisterOnBackInvokedCallback(callback);
+ return;
+ }
if (!mAllCallbacks.containsKey(callback)) {
if (DEBUG) {
Log.i(TAG, "Callback not found. returning...");
@@ -153,6 +163,9 @@
}
mAllCallbacks.clear();
mOnBackInvokedCallbacks.clear();
+ if (mImeDispatcher != null) {
+ mImeDispatcher = null;
+ }
}
private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) {
@@ -160,14 +173,18 @@
return;
}
try {
- if (callback == null) {
- mWindowSession.setOnBackInvokedCallbackInfo(mWindow, null);
- } else {
+ OnBackInvokedCallbackInfo callbackInfo = null;
+ if (callback != null) {
int priority = mAllCallbacks.get(callback);
- mWindowSession.setOnBackInvokedCallbackInfo(
- mWindow, new OnBackInvokedCallbackInfo(
- new OnBackInvokedCallbackWrapper(callback), priority));
+ final IOnBackInvokedCallback iCallback =
+ callback instanceof ImeOnBackInvokedDispatcher
+ .ImeOnBackInvokedCallback
+ ? ((ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
+ callback).getIOnBackInvokedCallback()
+ : new OnBackInvokedCallbackWrapper(callback);
+ callbackInfo = new OnBackInvokedCallbackInfo(iCallback, priority);
}
+ mWindowSession.setOnBackInvokedCallbackInfo(mWindow, callbackInfo);
if (DEBUG && callback == null) {
Log.d(TAG, TextUtils.formatSimple("setTopOnBackInvokedCallback(null) Callers:%s",
Debug.getCallers(5, " ")));
@@ -190,7 +207,7 @@
return null;
}
- private static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
+ static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
private final WeakReference<OnBackInvokedCallback> mCallback;
OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
@@ -270,4 +287,10 @@
return featureFlagEnabled && (appRequestsPredictiveBack || ALWAYS_ENFORCE_PREDICTIVE_BACK);
}
+
+ @Override
+ public void setImeOnBackInvokedDispatcher(
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
+ mImeDispatcher = imeDispatcher;
+ }
}
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 7db4243..0976f45 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -21,8 +21,10 @@
import android.annotation.AnyThread;
import android.annotation.BinderThread;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.app.IWindowToken;
import android.app.ResourcesManager;
import android.content.Context;
@@ -33,7 +35,6 @@
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.IWindowManager;
@@ -42,6 +43,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.ref.WeakReference;
@@ -76,7 +78,7 @@
private boolean mAttachToWindowContainer;
- private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Handler mHandler = ActivityThread.currentActivityThread().getHandler();
/**
* Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient}
@@ -188,8 +190,8 @@
@BinderThread
@Override
public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
- mHandler.post(() -> onConfigurationChanged(newConfig, newDisplayId,
- true /* shouldReportConfigChange */));
+ mHandler.post(PooledLambda.obtainRunnable(this::onConfigurationChanged, newConfig,
+ newDisplayId, true /* shouldReportConfigChange */).recycleOnUse());
}
// TODO(b/192048581): rewrite this method based on WindowContext and WindowProviderService
@@ -279,12 +281,16 @@
@BinderThread
@Override
public void onWindowTokenRemoved() {
- mHandler.post(() -> {
- final Context context = mContextRef.get();
- if (context != null) {
- context.destroy();
- mContextRef.clear();
- }
- });
+ mHandler.post(PooledLambda.obtainRunnable(
+ WindowTokenClient::onWindowTokenRemovedInner, this).recycleOnUse());
+ }
+
+ @MainThread
+ private void onWindowTokenRemovedInner() {
+ final Context context = mContextRef.get();
+ if (context != null) {
+ context.destroy();
+ mContextRef.clear();
+ }
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index f0a685e..781b6d5 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -245,7 +245,7 @@
SystemUiDeviceConfigFlags.IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP,
DEFAULT_IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP);
- private static final int DEFAULT_LIST_VIEW_UPDATE_DELAY_MS = 250;
+ private static final int DEFAULT_LIST_VIEW_UPDATE_DELAY_MS = 125;
@VisibleForTesting
int mListViewUpdateDelayMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -971,7 +971,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_COPY,
"",
- -1);
+ -1,
+ false);
setResult(RESULT_OK);
finish();
@@ -1155,7 +1156,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_NEARBY,
"",
- -1);
+ -1,
+ false);
// Action bar is user-independent, always start as primary
safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
finish();
@@ -1177,7 +1179,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_EDIT,
"",
- -1);
+ -1,
+ false);
// Action bar is user-independent, always start as primary
safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
finish();
@@ -1754,7 +1757,8 @@
target.getComponentName().getPackageName()
+ target.getTitle().toString(),
mMaxHashSaltDays);
- directTargetAlsoRanked = getRankedPosition((SelectableTargetInfo) targetInfo);
+ SelectableTargetInfo selectableTargetInfo = (SelectableTargetInfo) targetInfo;
+ directTargetAlsoRanked = getRankedPosition(selectableTargetInfo);
if (mCallerChooserTargets != null) {
numCallerProvided = mCallerChooserTargets.length;
@@ -1762,7 +1766,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_SERVICE,
targetInfo.getResolveInfo().activityInfo.processName,
- value
+ value,
+ selectableTargetInfo.isPinned()
);
break;
case ChooserListAdapter.TARGET_CALLER:
@@ -1773,7 +1778,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_APP,
targetInfo.getResolveInfo().activityInfo.processName,
- value
+ value,
+ targetInfo.isPinned()
);
break;
case ChooserListAdapter.TARGET_STANDARD_AZ:
@@ -1784,7 +1790,8 @@
getChooserActivityLogger().logShareTargetSelected(
SELECTION_TYPE_STANDARD,
targetInfo.getResolveInfo().activityInfo.processName,
- value
+ value,
+ false
);
break;
}
diff --git a/core/java/com/android/internal/app/ChooserActivityLogger.java b/core/java/com/android/internal/app/ChooserActivityLogger.java
index 3217307..bb7d50a 100644
--- a/core/java/com/android/internal/app/ChooserActivityLogger.java
+++ b/core/java/com/android/internal/app/ChooserActivityLogger.java
@@ -34,7 +34,8 @@
int appProvidedApp, boolean isWorkprofile, int previewType, String intent);
/** Logs a UiEventReported event for the system sharesheet when the user selects a target. */
- void logShareTargetSelected(int targetType, String packageName, int positionPicked);
+ void logShareTargetSelected(int targetType, String packageName, int positionPicked,
+ boolean isPinned);
/** Logs a UiEventReported event for the system sharesheet being triggered by the user. */
default void logSharesheetTriggered() {
diff --git a/core/java/com/android/internal/app/ChooserActivityLoggerImpl.java b/core/java/com/android/internal/app/ChooserActivityLoggerImpl.java
index 48bdba3..e3cc4f1 100644
--- a/core/java/com/android/internal/app/ChooserActivityLoggerImpl.java
+++ b/core/java/com/android/internal/app/ChooserActivityLoggerImpl.java
@@ -51,12 +51,14 @@
}
@Override
- public void logShareTargetSelected(int targetType, String packageName, int positionPicked) {
+ public void logShareTargetSelected(int targetType, String packageName, int positionPicked,
+ boolean isPinned) {
FrameworkStatsLog.write(FrameworkStatsLog.RANKING_SELECTED,
/* event_id = 1 */ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(),
/* package_name = 2 */ packageName,
/* instance_id = 3 */ getInstanceId().getId(),
- /* position_picked = 4 */ positionPicked);
+ /* position_picked = 4 */ positionPicked,
+ /* is_pinned = 5 */ isPinned);
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index c5b21ac..e7f80a7 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -589,7 +589,7 @@
MetricsLogger metricsLogger = new MetricsLogger();
LogMaker log = new LogMaker(MetricsEvent.ACTION_TARGET_SELECTED);
log.setComponentName(mRankerServiceName);
- log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, mAnnotationsUsed);
+ log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, mAnnotationsUsed ? 1 : 0);
log.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, selectedPos);
metricsLogger.write(log);
}
diff --git a/core/java/com/android/internal/app/UnlaunchableAppActivity.java b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
index 957a636..e56d92b 100644
--- a/core/java/com/android/internal/app/UnlaunchableAppActivity.java
+++ b/core/java/com/android/internal/app/UnlaunchableAppActivity.java
@@ -91,7 +91,12 @@
} else {
builder.setPositiveButton(R.string.ok, null);
}
- builder.show();
+ final AlertDialog dialog = builder.create();
+ dialog.create();
+ // Prevents screen overlay attack.
+ getWindow().setHideOverlayWindows(true);
+ dialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
+ dialog.show();
}
private String getDialogTitle() {
diff --git a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
index 402d7fe..4e1ecc2 100644
--- a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
+++ b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
@@ -36,6 +36,7 @@
import android.util.Log;
import android.util.LongSparseArray;
import android.view.ViewRootImpl;
+import android.view.ViewTreeObserver;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -232,9 +233,12 @@
private final ArraySet<BackgroundBlurDrawable> mDrawables = new ArraySet();
@GuardedBy("mRtLock")
private final LongSparseArray<ArraySet<Runnable>> mFrameRtUpdates = new LongSparseArray();
+ private long mLastFrameNumber = 0;
+ private BlurRegion[] mLastFrameBlurRegions = null;
private final ViewRootImpl mViewRoot;
private BlurRegion[] mTmpBlurRegionsForFrame = new BlurRegion[0];
private boolean mHasUiUpdates;
+ private ViewTreeObserver.OnPreDrawListener mOnPreDrawListener;
public Aggregator(ViewRootImpl viewRoot) {
mViewRoot = viewRoot;
@@ -277,6 +281,38 @@
Log.d(TAG, "Remove " + drawable);
}
}
+
+ if (mOnPreDrawListener == null && mViewRoot.getView() != null
+ && hasRegions()) {
+ registerPreDrawListener();
+ }
+ }
+
+ private void registerPreDrawListener() {
+ mOnPreDrawListener = () -> {
+ final boolean hasUiUpdates = hasUpdates();
+
+ if (hasUiUpdates || hasRegions()) {
+ final BlurRegion[] blurRegionsForNextFrame = getBlurRegionsCopyForRT();
+
+ mViewRoot.registerRtFrameCallback(frame -> {
+ synchronized (mRtLock) {
+ mLastFrameNumber = frame;
+ mLastFrameBlurRegions = blurRegionsForNextFrame;
+ handleDispatchBlurTransactionLocked(
+ frame, blurRegionsForNextFrame, hasUiUpdates);
+ }
+ });
+ }
+ if (!hasRegions() && mViewRoot.getView() != null) {
+ mViewRoot.getView().getViewTreeObserver()
+ .removeOnPreDrawListener(mOnPreDrawListener);
+ mOnPreDrawListener = null;
+ }
+ return true;
+ };
+
+ mViewRoot.getView().getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);
}
// Called from a thread pool
@@ -290,7 +326,14 @@
mFrameRtUpdates.put(frameNumber, frameRtUpdates);
}
frameRtUpdates.add(update);
+
+ if (mLastFrameNumber == frameNumber) {
+ // The transaction for this frame has already been sent, so we have to manually
+ // trigger sending a transaction here in order to apply this position update
+ handleDispatchBlurTransactionLocked(frameNumber, mLastFrameBlurRegions, true);
+ }
}
+
}
/**
@@ -329,29 +372,27 @@
/**
* Called on RenderThread.
*
- * @return all blur regions if there are any ui or position updates for this frame,
- * null otherwise
+ * @return true if it is necessary to send an update to Sf this frame
*/
+ @GuardedBy("mRtLock")
@VisibleForTesting
- public float[][] getBlurRegionsToDispatchToSf(long frameNumber,
- BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) {
- synchronized (mRtLock) {
- if (!hasUiUpdatesForFrame && (mFrameRtUpdates.size() == 0
- || mFrameRtUpdates.keyAt(0) > frameNumber)) {
- return null;
- }
+ public float[][] getBlurRegionsForFrameLocked(long frameNumber,
+ BlurRegion[] blurRegionsForFrame, boolean forceUpdate) {
+ if (!forceUpdate && (mFrameRtUpdates.size() == 0
+ || mFrameRtUpdates.keyAt(0) > frameNumber)) {
+ return null;
+ }
- // mFrameRtUpdates holds position updates coming from a thread pool span from
- // RenderThread. At this point, all position updates for frame frameNumber should
- // have been added to mFrameRtUpdates.
- // Here, we apply all updates for frames <= frameNumber in case some previous update
- // has been missed. This also protects mFrameRtUpdates from memory leaks.
- while (mFrameRtUpdates.size() != 0 && mFrameRtUpdates.keyAt(0) <= frameNumber) {
- final ArraySet<Runnable> frameUpdates = mFrameRtUpdates.valueAt(0);
- mFrameRtUpdates.removeAt(0);
- for (int i = 0; i < frameUpdates.size(); i++) {
- frameUpdates.valueAt(i).run();
- }
+ // mFrameRtUpdates holds position updates coming from a thread pool span from
+ // RenderThread. At this point, all position updates for frame frameNumber should
+ // have been added to mFrameRtUpdates.
+ // Here, we apply all updates for frames <= frameNumber in case some previous update
+ // has been missed. This also protects mFrameRtUpdates from memory leaks.
+ while (mFrameRtUpdates.size() != 0 && mFrameRtUpdates.keyAt(0) <= frameNumber) {
+ final ArraySet<Runnable> frameUpdates = mFrameRtUpdates.valueAt(0);
+ mFrameRtUpdates.removeAt(0);
+ for (int i = 0; i < frameUpdates.size(); i++) {
+ frameUpdates.valueAt(i).run();
}
}
@@ -370,13 +411,13 @@
}
/**
- * Called on RenderThread in FrameDrawingCallback.
- * Dispatch all blur regions if there are any ui or position updates.
+ * Dispatch all blur regions if there are any ui or position updates for that frame.
*/
- public void dispatchBlurTransactionIfNeeded(long frameNumber,
- BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) {
- final float[][] blurRegionsArray = getBlurRegionsToDispatchToSf(frameNumber,
- blurRegionsForFrame, hasUiUpdatesForFrame);
+ @GuardedBy("mRtLock")
+ private void handleDispatchBlurTransactionLocked(long frameNumber, BlurRegion[] blurRegions,
+ boolean forceUpdate) {
+ float[][] blurRegionsArray =
+ getBlurRegionsForFrameLocked(frameNumber, blurRegions, forceUpdate);
if (blurRegionsArray != null) {
mViewRoot.dispatchBlurRegions(blurRegionsArray, frameNumber);
}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 1b52aa9..e466c88 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -45,6 +45,7 @@
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
@@ -192,6 +193,7 @@
public static final int CUJ_SPLIT_SCREEN_EXIT = 50;
public static final int CUJ_LOCKSCREEN_LAUNCH_CAMERA = 51; // reserved.
public static final int CUJ_SPLIT_SCREEN_RESIZE = 52;
+ public static final int CUJ_SETTINGS_SLIDER = 53;
private static final int NO_STATSD_LOGGING = -1;
@@ -253,6 +255,7 @@
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_EXIT,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER,
};
private static volatile InteractionJankMonitor sInstance;
@@ -325,7 +328,8 @@
CUJ_SPLIT_SCREEN_ENTER,
CUJ_SPLIT_SCREEN_EXIT,
CUJ_LOCKSCREEN_LAUNCH_CAMERA,
- CUJ_SPLIT_SCREEN_RESIZE
+ CUJ_SPLIT_SCREEN_RESIZE,
+ CUJ_SETTINGS_SLIDER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -750,6 +754,8 @@
return "CUJ_LOCKSCREEN_LAUNCH_CAMERA";
case CUJ_SPLIT_SCREEN_RESIZE:
return "CUJ_SPLIT_SCREEN_RESIZE";
+ case CUJ_SETTINGS_SLIDER:
+ return "SETTINGS_SLIDER";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/logging/UiEventLoggerImpl.java b/core/java/com/android/internal/logging/UiEventLoggerImpl.java
index 983e0fe..ffbf646 100644
--- a/core/java/com/android/internal/logging/UiEventLoggerImpl.java
+++ b/core/java/com/android/internal/logging/UiEventLoggerImpl.java
@@ -69,7 +69,8 @@
/* event_id = 1 */ eventID,
/* package_name = 2 */ packageName,
/* instance_id = 3 */ 0,
- /* position_picked = 4 */ position);
+ /* position_picked = 4 */ position,
+ /* is_pinned = 5 */ false);
}
}
@@ -82,7 +83,8 @@
/* event_id = 1 */ eventID,
/* package_name = 2 */ packageName,
/* instance_id = 3 */ instance.getId(),
- /* position_picked = 4 */ position);
+ /* position_picked = 4 */ position,
+ /* is_pinned = 5 */ false);
} else if ((eventID > 0)) {
logWithPosition(event, uid, packageName, position);
}
diff --git a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
index 3eb9804..5adaf4f 100644
--- a/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
+++ b/core/java/com/android/internal/notification/NotificationAccessConfirmationActivityContract.java
@@ -28,18 +28,15 @@
public final class NotificationAccessConfirmationActivityContract {
public static final String EXTRA_USER_ID = "user_id";
public static final String EXTRA_COMPONENT_NAME = "component_name";
- public static final String EXTRA_PACKAGE_TITLE = "package_title";
/**
* Creates a launcher intent for NotificationAccessConfirmationActivity.
*/
- public static Intent launcherIntent(Context context, int userId, ComponentName component,
- String packageTitle) {
+ public static Intent launcherIntent(Context context, int userId, ComponentName component) {
return new Intent()
.setComponent(ComponentName.unflattenFromString(context.getString(
R.string.config_notificationAccessConfirmationActivity)))
.putExtra(EXTRA_USER_ID, userId)
- .putExtra(EXTRA_COMPONENT_NAME, component)
- .putExtra(EXTRA_PACKAGE_TITLE, packageTitle);
+ .putExtra(EXTRA_COMPONENT_NAME, component);
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e4dec56..b03a8cb 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -167,7 +167,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- static final int VERSION = 207;
+ static final int VERSION = 208;
// The maximum number of names wakelocks we will keep track of
// per uid; once the limit is reached, we batch the remaining wakelocks
@@ -472,9 +472,9 @@
mNumSingleUidCpuTimeReads++;
LongArrayMultiStateCounter onBatteryCounter =
- u.getProcStateTimeCounter().getCounter();
+ u.getProcStateTimeCounter(timestampMs).getCounter();
LongArrayMultiStateCounter onBatteryScreenOffCounter =
- u.getProcStateScreenOffTimeCounter().getCounter();
+ u.getProcStateScreenOffTimeCounter(timestampMs).getCounter();
mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, timestampMs);
mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, timestampMs);
@@ -543,9 +543,9 @@
final long timestampMs = mClock.elapsedRealtime();
final LongArrayMultiStateCounter onBatteryCounter =
- u.getProcStateTimeCounter().getCounter();
+ u.getProcStateTimeCounter(timestampMs).getCounter();
final LongArrayMultiStateCounter onBatteryScreenOffCounter =
- u.getProcStateScreenOffTimeCounter().getCounter();
+ u.getProcStateScreenOffTimeCounter(timestampMs).getCounter();
if (uid == parentUid || Process.isSdkSandboxUid(uid)) {
mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, timestampMs);
@@ -3981,8 +3981,7 @@
if (idxObj != null) {
idx = idxObj;
if ((idx & TAG_FIRST_OCCURRENCE_FLAG) != 0) {
- idx &= ~TAG_FIRST_OCCURRENCE_FLAG;
- mHistoryTagPool.put(tag, idx);
+ mHistoryTagPool.put(tag, idx & ~TAG_FIRST_OCCURRENCE_FLAG);
}
return idx;
} else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) {
@@ -8935,8 +8934,8 @@
@VisibleForTesting
public void setProcessStateForTest(int procState, long elapsedTimeMs) {
mProcessState = procState;
- getProcStateTimeCounter().setState(procState, elapsedTimeMs);
- getProcStateScreenOffTimeCounter().setState(procState, elapsedTimeMs);
+ getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs);
+ getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs);
final int batteryConsumerProcessState =
mapUidProcessStateToBatteryConsumerProcessState(procState);
getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs);
@@ -9095,12 +9094,11 @@
}
@GuardedBy("mBsi")
- private void ensureMultiStateCounters() {
+ private void ensureMultiStateCounters(long timestampMs) {
if (mProcStateTimeMs != null) {
return;
}
- final long timestampMs = mBsi.mClock.elapsedRealtime();
mProcStateTimeMs =
new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase,
PROC_STATE_TIME_COUNTER_STATE_COUNT, mBsi.getCpuFreqCount(),
@@ -9112,14 +9110,14 @@
}
@GuardedBy("mBsi")
- private TimeInFreqMultiStateCounter getProcStateTimeCounter() {
- ensureMultiStateCounters();
+ private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) {
+ ensureMultiStateCounters(timestampMs);
return mProcStateTimeMs;
}
@GuardedBy("mBsi")
- private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter() {
- ensureMultiStateCounters();
+ private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) {
+ ensureMultiStateCounters(timestampMs);
return mProcStateScreenOffTimeMs;
}
@@ -11972,9 +11970,9 @@
mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs);
LongArrayMultiStateCounter onBatteryCounter =
- getProcStateTimeCounter().getCounter();
+ getProcStateTimeCounter(elapsedRealtimeMs).getCounter();
LongArrayMultiStateCounter onBatteryScreenOffCounter =
- getProcStateScreenOffTimeCounter().getCounter();
+ getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter();
onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs);
onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs);
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 81c6ee7..09e409b 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.hardware.SensorManager;
+import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
@@ -26,6 +27,7 @@
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -230,7 +232,52 @@
batteryUsageStatsBuilder.setBatteryHistory(batteryStatsHistory);
}
- return batteryUsageStatsBuilder.build();
+ BatteryUsageStats stats = batteryUsageStatsBuilder.build();
+ if (includeProcessStateData) {
+ verify(stats);
+ }
+ return stats;
+ }
+
+ // STOPSHIP(b/229906525): remove verification before shipping
+ private static boolean sErrorReported;
+ private void verify(BatteryUsageStats stats) {
+ if (sErrorReported) {
+ return;
+ }
+
+ final double precision = 2.0; // Allow rounding errors up to 2 mAh
+ final int[] components =
+ {BatteryConsumer.POWER_COMPONENT_CPU,
+ BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
+ BatteryConsumer.POWER_COMPONENT_WIFI,
+ BatteryConsumer.POWER_COMPONENT_BLUETOOTH};
+ final int[] states =
+ {BatteryConsumer.PROCESS_STATE_FOREGROUND,
+ BatteryConsumer.PROCESS_STATE_BACKGROUND,
+ BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE,
+ BatteryConsumer.PROCESS_STATE_CACHED};
+ for (UidBatteryConsumer ubc : stats.getUidBatteryConsumers()) {
+ for (int component : components) {
+ double consumedPower = ubc.getConsumedPower(ubc.getKey(component));
+ double sumStates = 0;
+ for (int state : states) {
+ sumStates += ubc.getConsumedPower(ubc.getKey(component, state));
+ }
+ if (sumStates > consumedPower + precision) {
+ String error = "Sum of states exceeds total. UID = " + ubc.getUid() + " "
+ + BatteryConsumer.powerComponentIdToString(component)
+ + " total = " + consumedPower + " states = " + sumStates;
+ if (!sErrorReported) {
+ Slog.wtf(TAG, error);
+ sErrorReported = true;
+ } else {
+ Slog.e(TAG, error);
+ }
+ return;
+ }
+ }
+ }
}
private long getProcessForegroundTimeMs(BatteryStats.Uid uid, long realtimeUs) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1db4bbb..ea5797d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1262,7 +1262,7 @@
}
}
- if (forceConsumingNavBar && !mDrawLegacyNavigationBarBackgroundHandled) {
+ if (forceConsumingNavBar && !hideNavigation && !mDrawLegacyNavigationBarBackgroundHandled) {
mBackgroundInsets = Insets.of(mLastLeftInset, 0, mLastRightInset, mLastBottomInset);
} else {
mBackgroundInsets = Insets.NONE;
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 46b4630..ef8f2db 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -88,7 +88,7 @@
in int notificationLocation, boolean modifiedBeforeSending);
void onNotificationSettingsViewed(String key);
void onNotificationBubbleChanged(String key, boolean isBubble, int flags);
- void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed, boolean isBubbleSuppressed);
+ void onBubbleMetadataFlagChanged(String key, int flags);
void hideCurrentInputMethodForBubbles();
void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
oneway void clearInlineReplyUriPermissions(String key);
diff --git a/core/java/com/android/internal/util/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index 397b2c0..62dea9d 100644
--- a/core/java/com/android/internal/util/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -137,6 +137,18 @@
*/
public static Bitmap buildScaledBitmap(Drawable drawable, int maxWidth,
int maxHeight) {
+ return buildScaledBitmap(drawable, maxWidth, maxHeight, false);
+ }
+
+ /**
+ * Convert a drawable to a bitmap, scaled to fit within maxWidth and maxHeight.
+ *
+ * @param allowUpscaling if true, the drawable will not only be scaled down, but also scaled up
+ * to fit within the maximum size given. This is useful for converting
+ * vectorized icons which usually have a very small intrinsic size.
+ */
+ public static Bitmap buildScaledBitmap(Drawable drawable, int maxWidth,
+ int maxHeight, boolean allowUpscaling) {
if (drawable == null) {
return null;
}
@@ -155,7 +167,9 @@
// a large notification icon if necessary
float ratio = Math.min((float) maxWidth / (float) originalWidth,
(float) maxHeight / (float) originalHeight);
- ratio = Math.min(1.0f, ratio);
+ if (!allowUpscaling) {
+ ratio = Math.min(1.0f, ratio);
+ }
int scaledWidth = (int) (ratio * originalWidth);
int scaledHeight = (int) (ratio * originalHeight);
Bitmap result = Bitmap.createBitmap(scaledWidth, scaledHeight, Config.ARGB_8888);
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index 40d89db..4e2526a 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -23,6 +23,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputMethodSubtype;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.IInputContext;
@@ -47,7 +48,8 @@
void unbindInput();
void startInput(in IBinder startInputToken, in IInputContext inputContext,
- in EditorInfo attribute, boolean restarting, int navigationBarFlags);
+ in EditorInfo attribute, boolean restarting, int navigationBarFlags,
+ in ImeOnBackInvokedDispatcher imeDispatcher);
void onNavButtonFlagsChanged(int navButtonFlags);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index d7bb2cb..3157760 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -20,6 +20,7 @@
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.view.inputmethod.EditorInfo;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
@@ -57,7 +58,7 @@
/* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
int windowFlags, in EditorInfo attribute, in IInputContext inputContext,
in IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion);
+ int unverifiedTargetSdkVersion, in ImeOnBackInvokedDispatcher imeDispatcher);
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index c0f7b41..4af28ea 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -47,6 +47,43 @@
return env;
}
+ struct {
+ jmethodID onTransactionHang;
+} gTransactionHangCallback;
+
+class TransactionHangCallbackWrapper : public LightRefBase<TransactionHangCallbackWrapper> {
+public:
+ explicit TransactionHangCallbackWrapper(JNIEnv* env, jobject jobject) {
+ env->GetJavaVM(&mVm);
+ mTransactionHangObject = env->NewGlobalRef(jobject);
+ LOG_ALWAYS_FATAL_IF(!mTransactionHangObject, "Failed to make global ref");
+ }
+
+ ~TransactionHangCallbackWrapper() {
+ if (mTransactionHangObject) {
+ getenv()->DeleteGlobalRef(mTransactionHangObject);
+ mTransactionHangObject = nullptr;
+ }
+ }
+
+ void onTransactionHang(bool isGpuHang) {
+ if (mTransactionHangObject) {
+ getenv()->CallVoidMethod(mTransactionHangObject,
+ gTransactionHangCallback.onTransactionHang, isGpuHang);
+ }
+ }
+
+private:
+ JavaVM* mVm;
+ jobject mTransactionHangObject;
+
+ JNIEnv* getenv() {
+ JNIEnv* env;
+ mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
+ return env;
+ }
+};
+
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
jboolean updateDestinationFrame) {
ScopedUtfChars name(env, jName);
@@ -141,6 +178,20 @@
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
return queue->isSameSurfaceControl(reinterpret_cast<SurfaceControl*>(surfaceControl));
}
+
+static void nativeSetTransactionHangCallback(JNIEnv* env, jclass clazz, jlong ptr,
+ jobject transactionHangCallback) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ if (transactionHangCallback == nullptr) {
+ queue->setTransactionHangCallback(nullptr);
+ } else {
+ sp<TransactionHangCallbackWrapper> wrapper =
+ new TransactionHangCallbackWrapper{env, transactionHangCallback};
+ queue->setTransactionHangCallback([wrapper](bool isGpuHang) {
+ wrapper->onTransactionHang(isGpuHang);
+ });
+ }
+}
static jobject nativeGatherPendingTransactions(JNIEnv* env, jclass clazz, jlong ptr,
jlong frameNum) {
@@ -163,7 +214,10 @@
{"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
{"nativeApplyPendingTransactions", "(JJ)V", (void*)nativeApplyPendingTransactions},
{"nativeIsSameSurfaceControl", "(JJ)Z", (void*)nativeIsSameSurfaceControl},
- {"nativeGatherPendingTransactions", "(JJ)Landroid/view/SurfaceControl$Transaction;", (void*)nativeGatherPendingTransactions}
+ {"nativeGatherPendingTransactions", "(JJ)Landroid/view/SurfaceControl$Transaction;", (void*)nativeGatherPendingTransactions},
+ {"nativeSetTransactionHangCallback",
+ "(JLandroid/graphics/BLASTBufferQueue$TransactionHangCallback;)V",
+ (void*)nativeSetTransactionHangCallback},
// clang-format on
};
@@ -180,6 +234,11 @@
jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
gTransactionConsumer.accept =
GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
+ jclass transactionHangClass =
+ FindClassOrDie(env, "android/graphics/BLASTBufferQueue$TransactionHangCallback");
+ gTransactionHangCallback.onTransactionHang =
+ GetMethodIDOrDie(env, transactionHangClass, "onTransactionHang", "(Z)V");
+
return 0;
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index b6fbe20..f24c666 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1264,6 +1264,12 @@
size_t numPositionMasks = 0;
size_t numIndexMasks = 0;
+ int audioFormat = audioFormatFromNative(nAudioProfile->format);
+ if (audioFormat == ENCODING_INVALID) {
+ ALOGW("Unknown native audio format for JAVA API: %u", nAudioProfile->format);
+ return AUDIO_JAVA_BAD_VALUE;
+ }
+
// count up how many masks are positional and indexed
for (size_t index = 0; index < nAudioProfile->num_channel_masks; index++) {
const audio_channel_mask_t mask = nAudioProfile->channel_masks[index];
@@ -1306,10 +1312,9 @@
ALOGW("Unknown encapsulation type for JAVA API: %u", nAudioProfile->encapsulation_type);
}
- *jAudioProfile =
- env->NewObject(gAudioProfileClass, gAudioProfileCstor,
- audioFormatFromNative(nAudioProfile->format), jSamplingRates.get(),
- jChannelMasks.get(), jChannelIndexMasks.get(), encapsulationType);
+ *jAudioProfile = env->NewObject(gAudioProfileClass, gAudioProfileCstor, audioFormat,
+ jSamplingRates.get(), jChannelMasks.get(),
+ jChannelIndexMasks.get(), encapsulationType);
if (*jAudioProfile == nullptr) {
return AUDIO_JAVA_ERROR;
@@ -1368,6 +1373,10 @@
jobject jAudioProfile = nullptr;
jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &nAudioPort->audio_profiles[i],
useInMask);
+ if (jStatus == AUDIO_JAVA_BAD_VALUE) {
+ // skipping Java layer unsupported audio formats
+ continue;
+ }
if (jStatus != NO_ERROR) {
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
@@ -2406,8 +2415,13 @@
goto exit;
}
for (size_t i = 0; i < numSurroundFormats; i++) {
- jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
- audioFormatFromNative(surroundFormats[i]));
+ int audioFormat = audioFormatFromNative(surroundFormats[i]);
+ if (audioFormat == ENCODING_INVALID) {
+ // skipping Java layer unsupported audio formats
+ ALOGW("Unknown surround native audio format for JAVA API: %u", surroundFormats[i]);
+ continue;
+ }
+ jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, audioFormat);
jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
env->DeleteLocalRef(surroundFormat);
@@ -2453,8 +2467,13 @@
goto exit;
}
for (size_t i = 0; i < numSurroundFormats; i++) {
- jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
- audioFormatFromNative(surroundFormats[i]));
+ int audioFormat = audioFormatFromNative(surroundFormats[i]);
+ if (audioFormat == ENCODING_INVALID) {
+ // skipping Java layer unsupported audio formats
+ ALOGW("Unknown surround native audio format for JAVA API: %u", surroundFormats[i]);
+ continue;
+ }
+ jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor, audioFormat);
env->CallObjectMethod(jSurroundFormats, gArrayListMethods.add, surroundFormat);
env->DeleteLocalRef(surroundFormat);
}
@@ -2919,6 +2938,10 @@
for (const auto &audioProfile : audioProfiles) {
jobject jAudioProfile;
jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &audioProfile, false);
+ if (jStatus == AUDIO_JAVA_BAD_VALUE) {
+ // skipping Java layer unsupported audio formats
+ continue;
+ }
if (jStatus != AUDIO_JAVA_SUCCESS) {
return jStatus;
}
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 43c1cfd..84ca1ba 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -239,8 +239,12 @@
char *tmp = const_cast<char *>(context.c_str());
int ret = setfilecon(path.c_str(), tmp);
- ALOGV("setFileCon(%s, %s) => %d", path.c_str(), context.c_str(), ret);
- return (ret == 0) ? true : false;
+ if (ret == 0) {
+ ALOGV("setFileCon(%s, %s) => %d", path.c_str(), context.c_str(), ret);
+ return true;
+ }
+ ALOGE("setFileCon(%s, %s) => %d, err: %s", path.c_str(), context.c_str(), ret, strerror(errno));
+ return false;
}
/*
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 217166c..0f328b0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6776,9 +6776,8 @@
</activity>
<activity android:name="com.android.server.logcat.LogAccessDialogActivity"
- android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight"
+ android:theme="@style/Theme.Translucent.NoTitleBar"
android:excludeFromRecents="true"
- android:label="@string/log_access_confirmation_title"
android:exported="false">
</activity>
@@ -7057,6 +7056,10 @@
android:permission="android.permission.BIND_JOB_SERVICE">
</service>
+ <service android:name="com.android.server.notification.ReviewNotificationPermissionsJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE">
+ </service>
+
<service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
android:exported="false">
<intent-filter>
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 95d2712..c54638a 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -45,3 +45,4 @@
# Telephony
per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS
+per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index d5174f8..cda353f 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -36,8 +36,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@string/config_headlineFontFamilyMedium"
- android:textColor="@color/resolver_empty_state_text"
+ android:textColor="?android:attr/textColorPrimary"
android:textSize="18sp"
+ android:lineHeight="24sp"
android:gravity="center_horizontal"
android:layout_centerHorizontal="true" />
<TextView
@@ -46,8 +47,9 @@
android:layout_marginTop="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="@color/resolver_empty_state_text"
+ android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
+ android:lineHeight="20sp"
android:gravity="center_horizontal"
android:layout_centerHorizontal="true" />
<Button
@@ -57,11 +59,13 @@
android:text="@string/resolver_switch_on_work"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:padding="12dp"
android:fontFamily="@string/config_headlineFontFamilyMedium"
android:textSize="14sp"
- android:textColor="?attr/colorAccent"
+ android:textColor="?android:attr/textColorPrimary"
android:layout_centerHorizontal="true"
- android:background="@drawable/resolver_turn_on_work_button_ripple_background"/>
+ android:background="@drawable/chooser_action_button_bg"
+ />
<ProgressBar
android:id="@+id/resolver_empty_state_progress"
style="@style/Widget.Material.Light.ProgressBar"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index cae6165..7dd7c52 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"by jou kalender in te gaan"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-boodskappe te stuur en te bekyk"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Lêers en dokumente"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Lêers en dokumente"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"kry toegang tot lêers en dokumente op jou toestel"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiek en ander oudio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"kry toegang tot oudiolêers op jou toestel"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto\'s en video\'s"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"kry toegang tot prente en videolêers op jou toestel"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musiek en oudio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"kry toegang tot musiek en oudio op jou toestel"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto\'s en video\'s"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"kry toegang tot foto\'s en video\'s op jou toestel"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"oudio op te neem"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fisieke aktiwiteit"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Moenie Steur Nie het verander"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tik om te kyk wat geblokkeer word."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Gaan kennisgewinginstellings na"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Vanaf Android 13 het programme wat jy installeer jou toestemming nodig om kennisgewings te stuur. Tik om hierdie toestemming vir bestaande programme te verander."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Herinner my later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Maak toe"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Stelsel"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8bac983..8d365f0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"ኤስኤምኤስ"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"የኤስኤምኤስ መልዕክቶችን ይላኩና ይመልከቱ"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ፋይሎች እና ሰነዶች"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ፋይሎች እና ሰነዶች"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ፋይሎች እና ሰነዶች ዘንድ በመሳሪያዎ ላይ ይድረሱ"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ሙዚቃ እና ሌላ ኦዲዮ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"በመሳሪያዎ ላይ የድምጽ ፋይሎችን ይድረሱ"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ፎቶዎች እና ቪዲዮዎች"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"በመሣሪያዎ ላይ ምስሎችን እና የቪዲዮ ፋይሎችን ይድረሱ"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"ሙዚቃ እና ኦዲዮ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"በመሣሪያዎ ላይ ሙዚቃን እና ኦዲዮን መድረስ"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ፎቶዎች እና ቪዲዮዎች"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"በመሣሪያዎ ላይ ፎቶዎችን እና ቪዲዮዎችን መድረስ"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ማይክሮፎን"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ኦዲዮ ይቅዱ"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"አካላዊ እንቅስቃሴ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"አትረብሽ ተቀይሯል"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ምን እንደታገደ ለመፈተሽ መታ ያድርጉ።"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"የማሳወቂያ ቅንብሮችን ይገምግሙ"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"ከAndroid 13 ጀምረው የሚጭኗቸው መተግበሪያዎች ማሳወቂያዎችን ለመላክ የእርስዎ ፈቃድ ያስፈልጋቸዋል። ይህን ፈቃድ ለነባር መተግበሪያዎች ለመቀየር መታ ያድርጉ።"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"በኋላ አስታውሰኝ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"አሰናብት"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ሥርዓት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 6134918..dcd38ff 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -309,12 +309,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"الوصول إلى تقويمك"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"إرسال رسائل قصيرة SMS وعرضها"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"الملفات والمستندات"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"الملفات والمستندات"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"الوصول إلى الملفات والمستندات على جهازك"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"الموسيقى والملفات الصوتية الأخرى"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"الوصول إلى الملفات الصوتية على جهازك"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"الصور والفيديوهات"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"الوصول إلى الصور وملفات الفيديو على جهازك"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"الموسيقى والمقاطع الصوتية"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"تسمح فئة أذونات التطبيق هذه بالوصول إلى الموسيقى والمقاطع الصوتية على جهازك."</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"الصور والفيديوهات"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"تسمح فئة أذونات التطبيق هذه بالوصول إلى الصور والفيديوهات على جهازك."</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"الميكروفون"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"تسجيل الصوت"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"النشاط البدني"</string>
@@ -354,7 +354,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"عرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"السماح للتطبيق بعرض الإشعارات كأنشطة بملء الشاشة على الأجهزة المُقفَلة"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"تثبيت اختصارات"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"للسماح لتطبيق بإضافة اختصارات على الشاشة الرئيسية بدون تدخل المستخدم."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"السماح لتطبيق بإضافة اختصارات على الشاشة الرئيسية بدون تدخل المستخدم."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"إزالة الاختصارات"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"للسماح للتطبيق بإزالة اختصارات من الشاشة الرئيسية بدون تدخل المستخدم."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"إعادة توجيه المكالمات الصادرة"</string>
@@ -589,11 +589,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"خطأ في المصادقة"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"أدخِل قفل الشاشة للمتابعة"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"اضغط بقوة على المستشعر."</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"اضغط بقوة على المستشعر"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"يُرجى تنظيف مستشعر بصمات الإصبع ثم إعادة المحاولة."</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"تنظيف المستشعر ثم إعادة المحاولة"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على المستشعر."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على المستشعر"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"تم تحريك الإصبع ببطء شديد. يُرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string>
@@ -1632,7 +1632,7 @@
<string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
<string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"آمن"</string>
<string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"نسيت النقش"</string>
- <string name="kg_wrong_pattern" msgid="1342812634464179931">"النقش غير صحيح"</string>
+ <string name="kg_wrong_pattern" msgid="1342812634464179931">"النقش غير صحيح."</string>
<string name="kg_wrong_password" msgid="2384677900494439426">"كلمة مرور خاطئة"</string>
<string name="kg_wrong_pin" msgid="3680925703673166482">"رقم تعريف شخصي خاطئ"</string>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"ارسم نقشك"</string>
@@ -1848,7 +1848,7 @@
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"العمل الثالث <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"طلب إدخال رقم التعريف الشخصي قبل إزالة التثبيت"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال النقش الخاص بإلغاء القفل قبل إزالة التثبيت"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"المطالبة بكلمة المرور قبل إزالة التثبيت"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"تم التثبيت بواسطة المشرف"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"تم التحديث بواسطة المشرف"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string>
@@ -2057,8 +2057,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"تم تغيير ميزة \"عدم الإزعاج\""</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"انقر للاطّلاع على ما تم حظره."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"مراجعة إعدادات الإشعارات"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"بدءً من نظام التشغيل Android 13، يجب أن تحصل التطبيقات التي تُثبِّتها على إذن لإرسال الإشعارات. انقر لتغيير هذا الإذن للتطبيقات الحالية."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"تذكيري لاحقًا"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"إغلاق"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"النظام"</string>
@@ -2106,7 +2105,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"سيظل البلوتوث مفعَّلاً أثناء استخدام \"وضع الطيران\"."</string>
<string name="car_loading_profile" msgid="8219978381196748070">"جارٍ التحميل"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + ملف واحد}zero{{file_name} + # ملف}two{{file_name} + ملفان}few{{file_name} + # ملفات}many{{file_name} + # ملفًا}other{{file_name} + # ملف}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ليس هناك أشخاص مقترحون للمشاركة معهم."</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ما مِن أشخاص مقترحين للمشاركة معهم."</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"قائمة التطبيقات"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"لم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"الشاشة الرئيسية"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 4f3ed4c..8a15378 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপোনাৰ কেলেণ্ডাৰ ব্যৱহাৰ কৰিব পাৰে"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"এছএমএছ"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"এছএমএছ বার্তা পঠিয়াব আৰু চাব পাৰে"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ফাইল আৰু নথি"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ফাইল আৰু নথি"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"আপোনাৰ ডিভাইচত থকা ফাইল আৰু নথি এক্সেছ কৰে"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"সংগীত আৰু অন্যান্য অডিঅ’"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"আপোনাৰ ডিভাইচত অডিঅ’ ফাইলসমূহ এক্সেছ কৰক"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ফট’ আৰু ভিডিঅ’"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"আপোনাৰ ডিভাইচত থকা প্ৰতিচ্ছবি আৰু ভিডিঅ’ ফাইলসমূহ এক্সেছ কৰক"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"সংগীত আৰু অডিঅ’"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"আপোনাৰ ডিভাইচত সংগীত আৰু অডিঅ’ এক্সেছ কৰক"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ফট’ আৰু ভিডিঅ’"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"আপোনাৰ ডিভাইচত ফট’ আৰু ভিডিঅ’ এক্সেছ কৰক"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্ৰ\'ফ\'ন"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিঅ\' ৰেকর্ড কৰিব পাৰে"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"শাৰীৰিক কাৰ্যকলাপ"</string>
@@ -1926,8 +1926,8 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"এই মুহূৰ্তত <xliff:g id="APP_NAME_0">%1$s</xliff:g> উপলব্ধ নহয়। ইয়াক <xliff:g id="APP_NAME_1">%2$s</xliff:g>এ পৰিচালনা কৰে।"</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"অধিক জানক"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"এপ্ আনপজ কৰক"</string>
- <string name="work_mode_off_title" msgid="961171256005852058">"কাম সম্পৰ্কীয় এপ্ অন কৰিবনে?"</string>
- <string name="work_mode_off_message" msgid="7319580997683623309">"আপোনাৰ কাম সম্পৰ্কীয় এপ্ আৰু জাননীৰ এক্সেছ পাওক"</string>
+ <string name="work_mode_off_title" msgid="961171256005852058">"কৰ্মস্থানৰ এপ্ অন কৰিবনে?"</string>
+ <string name="work_mode_off_message" msgid="7319580997683623309">"আপোনাৰ কৰ্মস্থানৰ এপ্ আৰু জাননীৰ এক্সেছ পাওক"</string>
<string name="work_mode_turn_on" msgid="3662561662475962285">"অন কৰক"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"এপ্টো উপলব্ধ নহয়"</string>
<string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"অসুবিধা নিদিব সলনি হৈছে"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"জাননীৰ ছেটিং পৰ্যালোচনা কৰক"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13ৰ পৰা, আপুনি ইনষ্টল কৰা এপক জাননী পঠিয়াবলৈ আপোনাৰ অনুমতিৰ প্ৰয়োজন। আগৰে পৰা থকা এপৰ বাবে এই অনুমতিটো সলনি কৰিবলৈ টিপক।"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"পাছত মনত পেলাই দিব"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"অগ্ৰাহ্য কৰক"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ছিষ্টেম"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 52a43af..644635a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"təqvimə daxil olun"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"göndərin və SMS mesajlarına baxın"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayllar & sənədlər"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fayllar və sənədlər"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızda fayllara və sənədlərə giriş"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqi və digər audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdakı audio fayllarına giriş"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto və videolar"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"cihazınızdakı şəkil və video fayllarına giriş"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musiqi və audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"cihazınızdakı musiqi və audioya giriş"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto və videolar"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"cihazınızdakı foto və videolara giriş"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"səsi qeydə alın"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziki fəaliyyət"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Narahat Etməyin\" rejimi dəyişdirildi"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nəyin blok edildiyini yoxlamaq üçün klikləyin."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Bildiriş ayarlarını nəzərdən keçirin"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13-dən başlayaraq quraşdırdığınız tətbiqlər bildiriş göndərmək üçün icazənizi tələb edir. Mövcud tətbiqlər üçün bu icazəni dəyişmək üçün toxunun."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Sonra xatırladın"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Qapadın"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
@@ -2104,7 +2103,7 @@
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fayl}other{{file_name} + # fayl}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Paylaşmaq üçün tövsiyə edilən bir kimsə yoxdur"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Tətbiq siyahısı"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Bu tətbiqə yazmaq icazəsi verilməyib, lakin, bu USB vasitəsilə səs yaza bilər."</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Tətbiqə qeydə almaq icazəsi verilməsə də, bu USB vasitəsilə səsi qeydə ala bilər."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Əsas səhifə"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Geri"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Son Tətbiqlər"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index e854f43..e1f2f9b 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fajlovi i dokumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fajlovi i dokumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"pristupanje fajlovima i dokumentima na uređaju"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika i drugi audio sadržaj"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audio fajlovima na uređaju"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Slike i video snimci"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup slikama i video fajlovima na uređaju"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika i zvuk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pristup muzici i audio sadržaju na uređaju"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Slike i video snimci"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pristup slikama i video snimcima na uređaju"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizičke aktivnosti"</string>
@@ -351,7 +351,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji da dodaje prečice na početni ekran bez intervencije korisnika."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"da dodaju prečice na početni ekran bez intervencije korisnika."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji da uklanja prečice sa početnog ekrana bez intervencije korisnika."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"preusmeravanje odlaznih poziva"</string>
@@ -595,7 +595,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promenite položaj prsta"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promenite položaj prsta"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte podešavanja obaveštenja"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Od Android-a 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podseti me kasnije"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3197b73..355e6244 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"атрымліваць доступ да вашага календара"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"адпраўляць і праглядаць SMS-паведамленні"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы і дакументы"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файлы і дакументы"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"доступ да файлаў і дакументаў на вашай прыладзе"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка і іншае аўдыя"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ да аўдыяфайлаў на вашай прыладзе"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фота і відэа"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"доступ да відарысаў і відэафайлаў на вашай прыладзе"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музыка і аўдыя"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"доступ да музыкі і аўдыя на вашай прыладзе"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Фота і відэа"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"доступ да фота і відэа на вашай прыладзе"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрафон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"запісваць аўдыя"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Фізічная актыўнасць"</string>
@@ -1226,7 +1226,7 @@
<string name="unsupported_display_size_show" msgid="980129850974919375">"Заўсёды паказваць"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Праграма <xliff:g id="APP_NAME">%1$s</xliff:g> была створана для несумяшчальнай версии АС Android і можа паводзіць сябе неспадзявана. Можа быць даступна абноўленая версія праграмы."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Заўсёды паказваць"</string>
- <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Праверыць на наяўнасць абнаўленняў"</string>
+ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Праверыць наяўнасць абнаўленняў"</string>
<string name="smv_application" msgid="3775183542777792638">"Прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> (працэс <xliff:g id="PROCESS">%2$s</xliff:g>) парушыла ўласную палітыку StrictMode."</string>
<string name="smv_process" msgid="1398801497130695446">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> парушыў уласную палітыку StrictMode."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Абнаўленне тэлефона…"</string>
@@ -1951,7 +1951,7 @@
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць планшэт."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць тэлефон."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Гэта праграма была створана для больш старой версіі Android і можа не працаваць належным чынам. Праверце наяўнасць абнаўленняў або звярніцеся да распрацоўшчыка."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць на наяўнасць абнаўленняў"</string>
+ <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць наяўнасць абнаўленняў"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Праглядзець праз праграму для SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Функцыі могуць быць абмежаваныя"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Зменены налады рэжыму \"Не турбаваць\""</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Націсніце, каб паглядзець заблакіраванае."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Праверце налады апавяшчэнняў"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Пачынаючы з версіі Android 13 усталяваным вамі праграмам неабходна даваць дазвол на адпраўку апавяшчэнняў. Націсніце, каб змяніць дазвол для існуючых праграм."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Нагадаць пазней"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Закрыць"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Сістэма"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index ee7af66..f34d878 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"има достъп до календара ви"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"да изпраща и преглежда SMS съобщения"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлове и документи"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файлове и документи"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"достъп до файловете и документите на устройството ви"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудиосъдържание"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да има достъп до аудиофайловете на устройството ви"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Снимки и видеоклипове"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"да има достъп до графичните и видеофайловете на устройството ви"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика и аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"достъп до музиката и аудиото на устройството ви"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Снимки и видеоклипове"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"достъп до снимките и видеоклиповете на устройството ви"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"записва звук"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физическа активност"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Настройките за „Не безпокойте“ са променени"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Докоснете, за да проверите какво е блокирано."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Преглед на настройките за известия"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"От Android 13 инсталираните от вас приложения трябва да получат разрешението ви, за да изпращат известия. Докоснете, за да промените това разрешение за съществуващите приложения."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Напомняне по-късно"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Отхвърляне"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b0a832e..49a5af9 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ফাইল ও ডকুমেন্ট"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ফাইল এবং ডকুমেন্ট"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"আপনার ডিভাইসে ফাইল ও ডকুমেন্ট অ্যাক্সেস করুন"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"মিউজিক ও অন্যান্য অডিও"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"আপনার ডিভাইসে অডিও ফাইল অ্যাক্সেস করুন"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ফটো ও ভিডিও"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"আপনার ডিভাইসে ছবি ও ভিডিও ফাইল অ্যাক্সেস করুন"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"মিউজিক এবং অডিও"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"আপনার ডিভাইসে মিউজিক এবং অডিও অ্যাক্সেস করুন"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ফটো এবং ভিডিও"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"আপনার ডিভাইসে ফটো এবং ভিডিও অ্যাক্সেস করুন"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"মাইক্রোফোন"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"অডিও রেকর্ড"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"শারীরিক অ্যাক্টিভিটি"</string>
@@ -349,7 +349,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"অ্যাপ্লিকেশনটিকে স্ট্যাটাস বার প্রসারিত বা সঙ্কুচিত করতে দেয়৷"</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখায়"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"এই অ্যাপকে লক করা ডিভাইসে ফুল স্ক্রিন অ্যাক্টিভিটি হিসাবে বিজ্ঞপ্তি দেখানোর অনুমতি দেয়"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"শর্টকাটগুলি ইনস্টল করে"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"শর্টকাট ইনস্টল করা"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণে শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"শর্টকাটগুলি আনইনস্টল করে"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"অ্যাপ্লিকেশানটিকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই হোমস্ক্রীণের শর্টকাটগুলি সরানোর অনুমতি দেয়৷"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'বিরক্ত করবে না\' মোডের সেটিং বদলে গেছে"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কী কী ব্লক করা আছে তা দেখতে ট্যাপ করুন।"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"বিজ্ঞপ্তির সেটিংস পর্যালোচনা করুন"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 থেকে শুরু করে, বিজ্ঞপ্তি পাঠানোর জন্য আপনার ইনস্টল করা অ্যাপকে অনুমতি নিতে হবে। বর্তমান অ্যাপের জন্য এই অনুমতি পরিবর্তন করতে ট্যাপ করুন।"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"পরে মনে করিয়ে দিও"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"বাতিল করুন"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"সিস্টেম"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index b73b6a9..f4e380b 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupa vašem kalendaru"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fajlovi i dokumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fajlovi i dokumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"pristup datotekama i dokumentima na vašem uređaju"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika i drugi zvučni zapisi"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audio fajlovima na vašem uređaju"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije i videozapisi"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup fajlovima slika i videozapisa na vašem uređaju"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika i zvuk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pristupanje muzici i zvuku na vašem uređaju"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotografije i videozapisi"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pristupanje fotografijama i videozapisima na vašem uređaju"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"snima zvuk"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizička aktivnost"</string>
@@ -595,7 +595,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pokušajte s drugim otiskom prsta"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte podesiti"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put blago promijenite položaj prsta"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put pomalo promijenite položaj prsta"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
@@ -640,8 +640,8 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"Previše je tamno. Pokušajte s jačim osvjetljenjem."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Odmaknite telefon."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Primaknite telefon."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"Podignite telefon."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"Spustite telefon."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"Pomjerite telefon naviše."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"Pomjerite telefon naniže."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Pomjerite telefon ulijevo."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Pomjerite telefon udesno."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Gledajte direktno u uređaj."</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način rada Ne ometaj je promijenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da provjerite šta je blokirano."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte postavke obavještenja"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Počevši od Androida 13, aplikacije koje instalirate trebaju odobrenje da šalju obavještenja. Dodirnite da promijenite ovo odobrenje za postojeće aplikacije."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podsjeti me kasnije"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
@@ -2103,7 +2102,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"Bluetooth će ostati uključen tokom načina rada u avionu"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Učitavanje"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} i # fajl}one{{file_name} i # fajl}few{{file_name} i # fajla}other{{file_name} i # fajlova}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nema preporučenih osoba za dijeljenje"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Nema preporučenih osoba s kojima biste dijelili"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista aplikacija"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ovoj aplikaciji nije dato odobrenje za snimanje, ali može snimati zvuk putem ovog USB uređaja."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Početna stranica"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index ded50c7..bbc1908 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"accedir al calendari"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar i llegir missatges SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxers i documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fitxers i documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"accedir als fitxers i documents del dispositiu"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música i altres fitxers d\'àudio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accedir a fitxers d\'àudio del dispositiu"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos i vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accedir a fitxers d\'imatge i de vídeo del dispositiu"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música i àudio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"accedir a la música i l\'àudio del dispositiu"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos i vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"accedir a les fotos i els vídeos del dispositiu"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micròfon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar àudio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activitat física"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"S\'ha canviat el mode No molestis"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca per consultar què s\'ha bloquejat."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Consulta la configuració de notificacions"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"A partir de la versió Android 13, les aplicacions que instal·les necessiten el teu permís per enviar notificacions. Toca per canviar aquest permís per a les aplicacions existents."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Recorda-m\'ho més tard"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ignora"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index aad6bc4..66c38aa 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"přístup ke kalendáři"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"odesílání a zobrazování zpráv SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Soubory a dokumenty"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Soubory a dokumenty"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"přístup k souborům a dokumentům v zařízení"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Hudba a ostatní zvuk"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"přístup ke zvukovým souborům v zařízení"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotky a videa"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"přístup k obrázkům a videosouborům v zařízení"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Hudba a zvuk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"přístup k hudbě a zvuku v zařízení"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotky a videa"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"přísutp k fotkám a videím v zařízení"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávání zvuku"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fyzická aktivita"</string>
@@ -591,7 +591,7 @@
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně zatlačte na senzor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Zatlačte silně na senzor"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
@@ -1846,7 +1846,7 @@
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Před uvolněním požádat o PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před uvolněním požádat o heslo"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"Nainstalováno administrátorem"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizováno administrátorem"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Nastavení režimu Nerušit se změnilo"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Klepnutím zkontrolujete, co je blokováno."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Zkontrolujte nastavení oznámení"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Počínaje systémem Android 13 od vás nainstalované aplikace potřebují oprávnění k odesílání oznámení. Klepnutím toto oprávnění změníte pro stávající aplikace."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Připomenout později"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavřít"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6c12cc2..6242a3d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"have adgang til din kalender"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og se sms-beskeder"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Filer og dokumenter"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"få adgang til filer og dokumenter på din enhed"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik og anden lyd"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Få adgang til lydfiler på din enhed"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Billeder og videoer"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Få adgang til videofiler på din enhed"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musik og lyd"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"adgang til musik og lyd på din enhed"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Billeder og videoer"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"adgang til billeder og videoer på din enhed"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"optage lyd"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Tilstanden Forstyr ikke blev ændret"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tryk for at se, hvad der er blokeret."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Gennemgå indstillinger for notifikationer"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Fra og med Android 13 skal de apps, som du installerer, have din tilladelse til at sende notifikationer. Tryk for at ændre denne indstilling for eksisterende apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Påmind mig senere"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Luk"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f8c7596..c62c4dc 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"auf deinen Kalender zugreifen"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS senden und abrufen"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Dateien und Dokumente"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Dateien und Dokumente"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"Auf Dateien und Dokumente auf deinem Gerät zugreifen"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik & andere Audiodateien"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Zugriff auf Audiodateien auf deinem Gerät"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos & Videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Zugriff auf Bild- und Videodateien auf deinem Gerät"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musik und Audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"Zugriff auf Musik und Audio auf deinem Gerät"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos und Videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"Zugriff auf Fotos und Videos auf deinem Gerät"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"Audio aufnehmen"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Körperliche Aktivität"</string>
@@ -594,7 +594,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Anderen Fingerabdruck verwenden"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zu hell"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Versuche, den Finger anders aufzulegen"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ändere jedes Mal die Position deines Fingers"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ändere jedes Mal leicht die Position deines Fingers"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerabdruck nicht erkannt"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„Bitte nicht stören“ wurde geändert"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tippe, um zu überprüfen, welche Inhalte blockiert werden."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Benachrichtigungseinstellungen überprüfen"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Ab Android 13 benötigen Apps, die du installierst, die Berechtigung zum Senden von Benachrichtigungen. Wenn du diese Berechtigung für bereits installierte Apps ändern möchtest, tippe hier."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Später erinnern"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Schließen"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e949ce1..2703510 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Αρχεία και έγγραφα"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Αρχεία και έγγραφα"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"πρόσβαση σε αρχεία και έγγραφα στη συσκευή σας"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Μουσική και άλλο ηχητικό περιεχόμενο"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"πρόσβαση σε αρχεία ήχου στη συσκευή σας"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Φωτογραφίες και βίντεο"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"πρόσβαση σε αρχεία εικόνας και βίντεο στη συσκευή σας"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Μουσική και ήχος"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"πρόσβαση στη μουσική και σε αρχεία ήχου στη συσκευή σας"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Φωτογραφίες και βίντεο"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"πρόσβαση στις φωτογραφίες και τα βίντεο στη συσκευή σας"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Μικρόφωνο"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογραφεί"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Σωματική δραστ/τητα"</string>
@@ -640,7 +640,7 @@
<string name="face_acquired_too_close" msgid="1628767882971469833">"Απομακρύνετε περισσότερο το τηλέφωνο."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Πλησιάστε περισσότερο το τηλέφωνο."</string>
<string name="face_acquired_too_high" msgid="4868033653626081839">"Μετακινήστε το τηλέφωνο πιο ψηλά."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"Μετακινήστε πιο χαμηλά το τηλέφωνο."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"Μετακινήστε το τηλέφωνο πιο χαμηλά."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Μετακινήστε το τηλέφωνο στα αριστερά."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Μετακινήστε το τηλέφωνο στα δεξιά."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Κοιτάξτε απευθείας τη συσκευή σας."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Η λειτουργία \"Μην ενοχλείτε\" άλλαξε"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Πατήστε για να ελέγξετε το περιεχόμενο που έχει αποκλειστεί."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Έλεγχος ρυθμίσεων ειδοποιήσεων"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Από το Android 13 και έπειτα, οι εφαρμογές που εγκαθιστάτε θα χρειάζονται την άδειά σας για την αποστολή ειδοποιήσεων. Πατήστε για να αλλάξετε αυτήν την άδεια για υπάρχουσες εφαρμογές."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Υπενθύμιση αργότερα"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Παράβλεψη"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Σύστημα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index aedac3e..0d892cf 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Files & documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Files and documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music & other audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos & videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Music and audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"access music and audio on your device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos and videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"access photos and videos on your device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 88fedc9..296db1c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Files & documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Files and documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music & other audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos & videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Music and audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"access music and audio on your device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos and videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"access photos and videos on your device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index dd9de67..9c26240 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Files & documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Files and documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music & other audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos & videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Music and audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"access music and audio on your device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos and videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"access photos and videos on your device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a953730..b3e4dbf 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Files & documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Files and documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music & other audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos & videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Music and audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"access music and audio on your device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos and videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"access photos and videos on your device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 0aa8b28..7439725 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"send and view SMS messages"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Files & documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Files and documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"access files and documents on your device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Music & other audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"access audio files on your device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos & videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"access images and video files on your device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Music and audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"access music and audio on your device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos and videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"access photos and videos on your device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"record audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Physical activity"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Review notification settings"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Starting in Android 13, apps that you install need your permission to send notifications. Tap to change this permission for existing apps."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Remind me later"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 62b2d76..1bf1cf1 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder al calendario"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Archivos y documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"Accede a archivos y documentos en tu dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otro contenido de audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio en tu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y videos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a los archivos de imagen y video en tu dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música y audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acceder a música y audio de tu dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos y videos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acceder a fotos y videos de tu dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividad física"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Se modificó la opción No interrumpir"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Presiona para consultar lo que está bloqueado."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Revisa la configuración de notificaciones"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"A partir de Android 13, las apps que instales necesitarán tu permiso a fin de enviar notificaciones. Presiona para cambiar este permiso para las apps existentes."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Recordarme más tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Descartar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d31705d..2d907e9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -248,7 +248,7 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe de errores"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Finalizar sesión"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Captura de pantalla"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Informar de un error"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Informar error"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Informe interactivo"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Usa esta opción en la mayoría de los casos. Te permite realizar un seguimiento del progreso del informe, introducir más información sobre el problema y hacer capturas de pantalla. Es posible que se omitan algunas secciones menos utilizadas y que requieran más tiempo."</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder a tu calendario"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Archivos y documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a archivos y documentos de tu dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otros archivos de audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio de tu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a los archivos de vídeo de tu dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música y audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acceder a música y audio de tu dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos y vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acceder a fotos y vídeos de tu dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabar audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividad física"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ha cambiado el modo No molestar"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca para consultar lo que se está bloqueando."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Consulta los ajustes de notificaciones"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"A partir de Android 13, las aplicaciones que instalas necesitan tu permiso para enviar notificaciones. Toca para cambiar este permiso en las aplicaciones que ya tengas."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Recordar más tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Cerrar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
@@ -2104,7 +2103,7 @@
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} y # archivo más}other{{file_name} y # archivos más}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hay sugerencias de personas con las que compartir"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicaciones"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación no tiene permiso para grabar, pero podría registrar audio con este dispositivo USB."</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación no tiene permiso para grabar, pero podría capturar audio con este dispositivo USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Inicio"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Atrás"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplicaciones recientes"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index abd3325..231cf4a 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"juurdepääs kalendrile"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"saata ja vaadata SMS-sõnumeid"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Failid ja dokumendid"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Failid ja dokumendid"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"juurdepääs teie seadmes olevatele failidele ja dokumentidele"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muusika ja muud helifailid"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääseda juurde teie seadmes olevatele helifailidele"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotod ja videod"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pääseda juurde teie seadmes olevatele pildi- ja videofailidele"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muusika ja heli"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"teie seadmes muusikale ja helile juurdepääsemine"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotod ja videod"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"teie seadmes fotodele ja videotele juurdepääsemine"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"heli salvestamine"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Füüsiline tegevus"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Kuva märguanded lukustatud seadmes täisekraantegevustena"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lubab rakendusel märguandeid lukustatud seadmes täisekraantegevustena kuvada"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Otseteede installimine"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lubab rakendusel lisada avakuva otseteid ilma kasutaja sekkumiseta."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"lubab rakendusel lisada avakuva otseteid ilma kasutaja sekkumiseta."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"otseteede desinstallimine"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Lubab rakendusel eemaldada avakuva otseteid ilma kasutaja sekkumiseta."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"marsruutige väljuvad kõned uuesti"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režiimi Mitte segada muudeti"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Puudutage, et kontrollida, mis on blokeeritud."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Vaadake üle märguandeseaded"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Alates operatsioonisüsteemist Android 13 vajavad installitavad rakendused märguannete saatmiseks teie luba. Puudutage, et muuta seda luba olemasolevate rakenduste jaoks."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Tuleta hiljem meelde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Loobu"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Süsteem"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 9652c9a..18b3bf6 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"atzitu egutegia"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMSak"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"bidali eta ikusi SMS mezuak"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxategiak eta dokumentuak"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"fitxategiak eta dokumentuak"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"gailuko fitxategiak eta dokumentuak atzitu"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika eta bestelako audioa"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"atzitu gailuko audio-fitxategiak"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Argazkiak eta bideoak"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"atzitu gailuko irudi- eta bideo-fitxategiak"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"musika eta audioa"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"atzitu gailuko musika eta audioak"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"argazkiak eta bideoak"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"atzitu gailuko argazkiak eta bideoak"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonoa"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabatu audioa"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisikoa"</string>
@@ -344,7 +344,7 @@
<string name="permlab_statusBar" msgid="8798267849526214017">"desgaitu edo aldatu egoera-barra"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"bihurtu egoera-barra"</string>
- <string name="permdesc_statusBarService" msgid="6652917399085712557">"Egoera-barra izatea baimentzen die aplikazioei."</string>
+ <string name="permdesc_statusBarService" msgid="6652917399085712557">"Egoera-barra izateko baimena ematen die aplikazioei."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"zabaldu/tolestu egoera-barra"</string>
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Egoera-barra zabaltzeko edo tolesteko baimena ematen die aplikazioei."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzea"</string>
@@ -481,7 +481,7 @@
<string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"salbuetsi audioa grabatzeko murriztapenen aurrean"</string>
<string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Salbuetsi aplikazioa audioa grabatzeko murriztapenen aurrean."</string>
<string name="permlab_acceptHandover" msgid="2925523073573116523">"jarraitu beste aplikazio batean hasitako deia"</string>
- <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Beste aplikazio batean hasitako dei bat jarraitzea baimentzen dio aplikazioari."</string>
+ <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Beste aplikazio batean hasitako dei batekin jarraitzeko baimena ematen die aplikazioei."</string>
<string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"irakurri telefono-zenbakiak"</string>
<string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Gailuaren telefono-zenbakiak atzitzeko baimena ematen die aplikazioei."</string>
<string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"mantendu piztuta autoko pantaila"</string>
@@ -551,7 +551,7 @@
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko baimena ematen die aplikazioei, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
- <string name="permdesc_nfc" msgid="8352737680695296741">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei."</string>
+ <string name="permdesc_nfc" msgid="8352737680695296741">"Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_disableKeyguard" msgid="3605253559020928505">"desgaitu pantailaren blokeoa"</string>
<string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Teklen blokeoa eta erlazionatutako pasahitz-segurtasuna desgaitzeko baimena ematen die aplikazioei. Adibidez, telefonoak teklen blokeoa desgaitzen du telefono-deiak jasotzen dituenean, eta berriro gaitzen du deiak amaitzean."</string>
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"eskatu pantailaren blokeoa konplexua izatea"</string>
@@ -639,8 +639,8 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"Ilunegi dago. Erabili argi gehiago."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Urrundu telefonoa."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Hurbildu telefonoa."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"Goratu telefonoa."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"Beheratu telefonoa."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"Igo telefonoa."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"Jaitsi telefonoa."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Mugitu telefonoa ezkerretara."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Mugitu telefonoa eskuinetara."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Begiratu zuzenago gailuari."</string>
@@ -704,7 +704,7 @@
<string name="permlab_bind_incall_service" msgid="5990625112603493016">"erabili pantaila deiak abian direnean"</string>
<string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Erabiltzaileak deiaren pantaila noiz eta nola ikusten duen kontrolatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"jardun interakzioan telefono-zerbitzuekin"</string>
- <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzea baimentzen die aplikazioei."</string>
+ <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzeko baimena ematen die aplikazioei."</string>
<string name="permlab_control_incall_experience" msgid="6436863486094352987">"eskaini erabiltzaileentzako aukerak deiak abian direnean"</string>
<string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Deiak abian direnean erabiltzeko aukera eskaintzea baimentzen die aplikazioei."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"irakurri sare-erabileraren historia"</string>
@@ -1881,9 +1881,9 @@
<string name="stk_cc_ussd_to_dial" msgid="3139884150741157610">"USSD eskaera ohiko deira aldatu da"</string>
<string name="stk_cc_ussd_to_ss" msgid="4826846653052609738">"USSD eskaera SS eskaerara aldatu da"</string>
<string name="stk_cc_ussd_to_ussd" msgid="8343001461299302472">"USSD eskaera berrira aldatu da"</string>
- <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD eskaera bideo-deira aldatu da"</string>
+ <string name="stk_cc_ussd_to_dial_video" msgid="429118590323618623">"USSD eskaera bideodeira aldatu da"</string>
<string name="stk_cc_ss_to_dial" msgid="4087396658768717077">"SS eskaera ohiko deira aldatu da"</string>
- <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS eskaera bideo-deira aldatu da"</string>
+ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS eskaera bideodeira aldatu da"</string>
<string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS eskaera USSD eskaerara aldatu da"</string>
<string name="stk_cc_ss_to_ss" msgid="132040645206514450">"SS eskaera berrira aldatu da"</string>
<string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Phishing-alerta"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ez molestatzeko modua aldatu da"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Sakatu zer dagoen blokeatuta ikusteko."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Berrikusi jakinarazpen-ezarpenak"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 ezkero, jakinarazpenak bidaltzeko baimena eman behar diezu instalatzen dituzun aplikazioei. Sakatu hau lehendik dauden aplikazioen baimenak aldatzeko."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Gogorarazi geroago"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Baztertu"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
@@ -2275,11 +2274,9 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Itzuli da <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> hizkuntzatik <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> hizkuntzara itzuli da mezua."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atzeko planoko jarduerak"</string>
- <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
- <skip />
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Aplikazio bat bateria agortzen ari da"</string>
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikazio bat aktibo dago oraindik"</string>
- <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
- <skip />
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"Atzeko planoan funtzionatzen ari da <xliff:g id="APP">%1$s</xliff:g>. Bateria-erabilera kudeatzeko, sakatu hau."</string>
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Baliteke <xliff:g id="APP">%1$s</xliff:g> aplikazioak bateriaren iraupenean eragina izatea. Sakatu hau aplikazio aktiboak ikusteko."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ikusi zer aplikazio dauden aktibo"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 8082401..1e0851b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"دسترسی به تقویم شما"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"پیامک"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"ارسال و مشاهده پیامکها"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"فایلها و اسناد"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"فایلها و سندها"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"دسترسی به فایلها و اسناد موجود در دستگاه"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"موسیقی و فایلهای صوتی دیگر"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"دسترسی به فایلهای صوتی موجود در دستگاه"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"عکسها و ویدیوها"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"دسترسی به فایلهای تصویری و ویدیویی موجود در دستگاه"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"موسیقی و صدا"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"دسترسی به موسیقی و صدا در دستگاه شما"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"عکسها و ویدیوها"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"دسترسی به عکسها و ویدیوها در دستگاه شما"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"میکروفن"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ضبط صدا"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"فعالیت فیزیکی"</string>
@@ -604,7 +604,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالتسنجی شد، لطفاً تأیید را فشار دهید"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"سختافزار اثرانگشت در دسترس نیست."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"اثر انگشت راهاندازی نشد"</string>
- <string name="fingerprint_error_timeout" msgid="2946635815726054226">"درنگ ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
+ <string name="fingerprint_error_timeout" msgid="2946635815726054226">"مهلت ثبت اثر انگشت بهپایان رسید. دوباره امتحان کنید."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"عملکرد اثر انگشت لغو شد."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"کاربر عملیات اثر انگشت را لغو کرد"</string>
<string name="fingerprint_error_lockout" msgid="7853461265604738671">"تلاشهای زیادی انجام شده است. بعداً دوباره امتحان کنید."</string>
@@ -734,7 +734,7 @@
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"حذف گواهیهای DRM"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"به برنامه امکان میدهد گواهیهای DRM را حذف کند. نباید برای برنامههای عادی هیچوقت لازم باشد."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"مقید به سرویس پیامرسانی شرکت مخابراتی"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"به کنترلکننده اجازه میدهد که به سطح بالای میانای کاربر سرویس پیامرسانی شرکت مخابراتی مقید شود. هرگز نباید برای برنامههای عادی مورد نیاز شود."</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"به کنترلکننده اجازه میدهد که به سطح بالای واسط کاربر سرویس پیامرسانی شرکت مخابراتی مقید شود. هرگز نباید برای برنامههای عادی مورد نیاز شود."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"اتصال به سرویسهای شرکت مخابراتی"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"به دارنده امکان میدهد به سرویسهای شرکت مخابراتی متصل شود. هرگز نباید برای برنامههای عادی مورد نیاز باشد."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"دسترسی به حالت «مزاحم نشوید»"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«مزاحم نشوید» تغییر کرده است"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"برای بررسی موارد مسدودشده ضربه بزنید."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"مرور تنظیمات اعلان"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"از Android نسخه ۱۳ به بعد، برنامههایی که نصب میکنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامههای موجود، ضربه بزنید."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"بعداً یادآوری شود"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"رد شدن"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"سیستم"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 52c1d26..15a257c 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Tiedostot ja dokumentit"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Tiedostot ja dokumentit"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"pääsyn laitteesi tiedostoihin ja dokumentteihin"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiikki ja muu audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääsy laitteesi audiotiedostoihin"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Kuvat ja videot"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pääsy laitteesi kuviin ja videotiedostoihin"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musiikki ja audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pääsy laitteen musiikkiin ja audioon"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Valokuvat ja videot"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pääsy laitteen kuviin ja videoihin"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Liikkuminen"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Älä häiritse ‑tila muuttui"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Napauta niin näet, mitä on estetty."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Tarkista ilmoitusasetukset"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Asentamasi sovellukset tarvitsevat sinulta luvan ilmoitusten lähettämiseen Android 13 ‑käyttöjärjestelmästä alkaen. Napauta muuttaaksesi nykyisten sovellusten lupia."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Muistuta myöhemmin"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ohita"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Järjestelmä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index fc7fc07..43f01f4 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Messagerie texte"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et afficher des messages texte"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fichiers et documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"accédez aux fichiers et aux documents sur votre appareil"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres fichiers audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accéder aux fichiers audio de votre appareil"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accéder aux fichiers d\'image et aux fichiers vidéo de votre appareil"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musique et audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"accédez aux fichiers musicaux et audio sur votre appareil"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos et vidéos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"accédez aux photos et aux vidéos sur votre appareil"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
@@ -349,7 +349,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"afficher les notifications en mode plein écran sur un appareil verrouillé"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'application d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"installer des raccourcis"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installer des raccourcis"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'application de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
@@ -427,7 +427,7 @@
<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="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="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</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>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Les paramètres du mode Ne pas déranger ont changé"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Touchez l\'écran pour vérifier ce qui est bloqué."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Examiner les paramètres de notification"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applications que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applications existantes."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Me rappeler plus tard"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Fermer"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a8082c6..ea20db2 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/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="byteShort" msgid="202579285008794431">"octet(s)"</string>
- <string name="kilobyteShort" msgid="2214285521564195803">"Ko"</string>
+ <string name="kilobyteShort" msgid="2214285521564195803">"ko"</string>
<string name="megabyteShort" msgid="6649361267635823443">"Mo"</string>
<string name="gigabyteShort" msgid="7515809460261287991">"Go"</string>
<string name="terabyteShort" msgid="1822367128583886496">"To"</string>
@@ -244,7 +244,7 @@
<string name="global_action_power_off" msgid="4404936470711393203">"Éteindre"</string>
<string name="global_action_power_options" msgid="1185286119330160073">"Marche/Arrêt"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Redémarrer"</string>
- <string name="global_action_emergency" msgid="1387617624177105088">"Urgences"</string>
+ <string name="global_action_emergency" msgid="1387617624177105088">"Urgence"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Rapport de bug"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Fermer la session"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Capture d\'écran"</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et consulter des SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fichiers et documents"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"accéder aux fichiers et documents sur votre appareil"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres contenus audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accès aux fichiers audio sur votre appareil"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"accès aux fichiers image et vidéo sur votre appareil"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musique et audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"accéder aux contenus musicaux et audio sur votre appareil"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Photos et vidéos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"accéder aux photos et aux vidéos sur votre appareil"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
@@ -594,7 +594,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de repositionner le doigt"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Changez légèrement de position chaque fois"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Changez légèrement de position à chaque fois"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Empreinte digitale non reconnue"</string>
@@ -639,7 +639,7 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez une éclairage plus lumineux."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Éloignez le téléphone."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Rapprochez le téléphone."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"Déplacez le téléphone vers le haut."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"Montez le téléphone."</string>
<string name="face_acquired_too_low" msgid="1512237819632165945">"Baissez le téléphone."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Déplacez le téléphone vers la gauche."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Déplacez le téléphone vers la droite."</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="7500692654885445299">"Urgences"</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">"Combinaison correcte !"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Veuillez réessayer."</string>
@@ -1709,7 +1709,7 @@
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour changer de fonctionnalité, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
<string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g>..."</string>
+ <string name="user_switching_message" msgid="1912993630661332336">"Passage à <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>
@@ -2044,8 +2044,8 @@
<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>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibreur pour les appels et les notifications"</string>
- <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Sons désactivés pour les appels et les notifications"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Les appels et les notifications vibreront"</string>
+ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Les appels et les notifications seront silencieux"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"Modifications du système"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne pas déranger"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nouveau : Le mode Ne pas déranger masque les notifications"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Le mode Ne pas déranger a été modifié"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Appuyez pour vérifier les contenus bloqués."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Consulter les paramètres de notification"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applis que vous installez ont besoin de votre autorisation pour vous envoyer des notifications. Appuyez pour modifier cette autorisation pour les applis déjà installées."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Plus tard"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Fermer"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
@@ -2275,11 +2274,9 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> traduit."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message en <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> traduit en <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
- <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
- <skip />
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Une appli décharge la batterie"</string>
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une appli est encore active"</string>
- <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
- <skip />
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan. Appuyez pour gérer l\'utilisation de la batterie."</string>
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut affecter l\'autonomie de la batterie. Appuyez pour consulter les applis actives."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 0393c4b..9a65373 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder ao teu calendario"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e consultar mensaxes de SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Ficheiros e documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a ficheiros e documentos do dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro contido de audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a ficheiros de audio do teu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acceder a ficheiros de imaxe e de vídeo do teu dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acceder a música e audio do dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acceder a fotos e vídeos do dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Actividade física"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo Non molestar cambiou"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca para comprobar o contido bloqueado."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Consulta a configuración de notificacións"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Desde Android 13, as aplicacións que instales necesitan o teu permiso para enviar notificacións. Toca para cambiar este permiso nas aplicacións que xa teñas."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Lembrarmo máis tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Pechar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
@@ -2104,7 +2103,7 @@
<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">"Non hai recomendacións de persoas coas que compartir contido"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicacións"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación non está autorizada a realizar gravacións, pero pode capturar audio a través deste dispositivo USB."</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta aplicación non está autorizada a realizar gravacións, pero podería capturar audio a través deste dispositivo USB."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Inicio"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Volver"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Aplicacións recentes"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 033f7ee..b572d2e 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS સંદેશા મોકલવાની અને જોવાની"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ફાઇલો અને દસ્તાવેજો"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ફાઇલો અને દસ્તાવેજો"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"તમારા ડિવાઇસ પર ફાઇલો અને દસ્તાવેજો ઍક્સેસ કરો"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"મ્યુઝિક અને અન્ય ઑડિયો"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"તમારા ડિવાઇસ પર ઑડિયો ફાઇલો ઍક્સેસ કરવા માટે"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ફોટા અને વીડિયો"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"તમારા ડિવાઇસ પર છબીઓ અને વીડિયો ફાઇલો ઍક્સેસ કરવા માટે"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"મ્યુઝિક અને ઑડિયો"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"તમારા ડિવાઇસ પર મ્યુઝિક અને ઑડિયો ઍક્સેસ કરવા માટે"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ફોટા અને વીડિયો"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"તમારા ડિવાઇસ પર ફોટા અને વીડિયો ઍક્સેસ કરવા માટે"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"માઇક્રોફોન"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ઑડિઓ રેકોર્ડ કરવાની"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"શારીરિક પ્રવૃત્તિ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ખલેલ પાડશો નહીંમાં ફેરફાર થયો છે"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"શું બ્લૉક કરેલ છે તે તપાસવા માટે ટૅપ કરો."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"નોટિફિકેશનના સેટિંગ રિવ્યૂ કરો"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13થી શરૂઆત કરીને, તમે જે પણ ઍપ ઇન્સ્ટૉલ કરશો, તેને નોટિફિકેશન મોકલવા માટે તમારી પરવાનગીની જરૂર રહેશે. હાલની બધી ઍપ માટે આ પરવાનગીમાં ફેરફાર કરવા માટે ટૅપ કરો."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"મને પછી યાદ અપાવજો"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"છોડી દો"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"સિસ્ટમ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f029822..1e0c317 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"फ़ाइलें और दस्तावेज़"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"फ़ाइलों और दस्तावेज़ों को ऐक्सेस करने की अनुमति"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"अपने डिवाइस पर मौजूद फ़ाइलें और दस्तावेज़ ऐक्सेस करने की अनुमति दें"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"संगीत और अन्य ऑडियो"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"आपके डिवाइस पर मौजूद, ऑडियो फ़ाइलों का ऐक्सेस"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फ़ोटो और वीडियो"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"आपके डिवाइस पर मौजूद, इमेज और वीडियो फ़ाइलों का ऐक्सेस"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"आपके डिवाइस पर संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"आपके डिवाइस पर फ़ोटो और वीडियो को ऐक्सेस करने की अनुमति"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफ़ोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक गतिविधि"</string>
@@ -2044,7 +2044,7 @@
<string name="log_access_do_not_show_again" msgid="1058690599083091552">"फिर से न दिखाएं"</string>
<string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> के हिस्से (स्लाइस) दिखाना चाहता है"</string>
<string name="screenshot_edit" msgid="7408934887203689207">"बदलाव करें"</string>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कॉल और सूचनाओं के लिए डिवाइस वाइब्रेट हाेगा"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कॉल और सूचनाओं आने पर डिवाइस वाइब्रेट हाेगा"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"कॉल और सूचनाओं के लिए डिवाइस म्यूट रहेगा"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"सिस्टम में हुए बदलाव"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"परेशान न करें"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"परेशान न करें की सुविधा बदल गई है"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"टैप करके देखें कि किन चीज़ों पर रोक लगाई गई है."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"सूचना सेटिंग देखें"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 में जो ऐप्लिकेशन इंस्टॉल किए जाएंगे, उन्हें आपको सूचनाएं भेजने के लिए अनुमति लेनी होगी. पहले से इंस्टॉल किए गए ऐप्लिकेशन को दी गई अनुमति बदलने के लिए टैप करें."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"बाद में याद दिलाएं"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"बंद करें"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टम"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 42adb5d..d52bb3d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupati kalendaru"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"slati i pregledavati SMS poruke"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Datoteke i dokumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Datoteke i dokumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"pristup datotekama i dokumentima na vašem uređaju"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Glazba i druge audiodatoteke"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audiodatotekama na uređaju"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije i videozapisi"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pristup slikama i videodatotekama na uređaju"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Glazba i zvuk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pristupite glazbi i zvuku na svom uređaju"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotografije i videozapisi"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pristupite fotografijama i videozapisima na svom uređaju"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"snimati zvuk"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Tjelesna aktivnost"</string>
@@ -350,7 +350,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Omogućuje aplikaciji proširivanje ili sažimanje trake statusa."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazivati obavijesti kao aktivnosti na cijelom zaslonu na zaključanom uređaju"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućuje aplikaciji da na zaključanom uređaju prikazuje obavijesti kao aktivnosti na cijelom zaslonu"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečaca"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečaca"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Aplikaciji omogućuje dodavanje prečaca početnog zaslona bez intervencije korisnika."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečaca"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Aplikaciji omogućuje uklanjanje prečaca početnog zaslona bez intervencije korisnika."</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Promijenjena je postavka Ne uznemiravaj"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste provjerili što je blokirano."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte postavke obavijesti"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Od Androida 13 aplikacije koje instalirate trebaju vaše dopuštenje za slanje obavijesti. Dodirnite da biste promijenili to dopuštenje za postojeće aplikacije."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podsjeti me kasnije"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sustav"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c02cff6..f3e8827 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"hozzáférés a naptárhoz"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS-ek küldése és megtekintése"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fájlok és dokumentumok"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fájlok és dokumentumok"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"hozzáférhet fájljaihoz és dokumentumaihoz az eszközén"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Zenék és más audiotartalmak"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"hozzáférés az eszközön található hangfájlokhoz"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotók és videók"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"hozzáférés az eszközön található videófájlokhoz"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Zene és hang"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"hozzáférés a zenékhez és más hanganyagokhoz az eszközön"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotók és videók"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"hozzáférés a fotókhoz és a videókhoz az eszközön"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"hanganyag rögzítése"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Testmozgás"</string>
@@ -349,7 +349,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Lehetővé teszi az alkalmazás számára, hogy váltson az állapotsor részletes és listanézete között."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Értesítések megjelenítése teljes képernyős tevékenységként zárolt eszközön"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lehetővé teszi az alkalmazás számára, hogy értesítéseket jelenítsen meg teljes képernyős tevékenységként zárolt eszközön."</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"parancsikonok telepítése"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Parancsikonok telepítése"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül adjon hozzá parancsikonokat a kezdőképernyőhöz."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"parancsikonok eltávolítása"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül távolítson el parancsikonokat a kezdőképernyőről."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Módosultak a Ne zavarjanak mód beállításai"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Koppintson a letiltott elemek megtekintéséhez."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Értesítési beállítások áttekintése"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Az Android 13-as rendszertől kezdődően a telepített alkalmazásoknak engedélyre van szükségük értesítések küldéséhez. Koppintással módosíthatja ezt az engedélyt a meglévő alkalmazások esetében."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Emlékeztessen később"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Bezárás"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Rendszer"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index b983004..88b692e 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"օգտագործել օրացույցը"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"ուղարկել և դիտել SMS-ները"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Ֆայլեր և փաստաթղթեր"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Ֆայլեր և փաստաթղթեր"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"սարքի ֆայլերի և փաստաթղթերի օգտագործման թույլտվություն"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Երաժշտություն և այլ աուդիո նյութեր"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"բացել ձեր սարքում պահված աուդիո ֆայլերը"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Լուսանկարներ և տեսանյութեր"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"բացել ձեր սարքում պահված գրաֆիկական և վիդեո ֆայլերը"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Երաժշտություն և աուդիո"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"սարքի երաժշտության և աուդիո ֆայլերի հասանելիություն"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Լուսանկարներ և տեսանյութեր"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"սարքի լուսանկարների և տեսանյութերի հասանելիություն"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Խոսափող"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ձայնագրել"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Ֆիզիկական ակտիվություն"</string>
@@ -438,7 +438,7 @@
<string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Այս հավելվածը կարող է ավելացնել, հեռացնել կամ փոխել օրացույցի միջոցառումները ձեր Android TV սարքում: Այս հավելվածը կարող է ուղարկել հաղորդագրություններ օրացույցի սեփականատերերի անունից կամ փոխել միջոցառումները առանց դրանց սեփականատերերին ծանուցելու:"</string>
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Այս հավելվածը կարող է ավելացնել, հեռացնել կամ փոխել օրացույցի միջոցառումները ձեր հեռախոսում: Այս հավելվածը կարող է ուղարկել հաղորդագրություններ օրացույցի սեփականատերերի անունից կամ փոխել միջոցառումները առանց դրանց սեփականատերերին ծանուցելու:"</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"օգտագործել տեղադրություն տրամադրող հավելվյալ հրամաններ"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Ծրագրին թույլ է տալիս օգտագործել տեղադրության մասին տվյալների աղբյուրների կառավարման լրացուցիչ հրահանգներ: Սա կարող է ծրագրին թույլ տալ միջամտել GPS-ի կամ տեղադրության մասին տվյալների այլ աղբյուրների գործառույթներին:"</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Հավելվածին թույլ է տալիս օգտագործել տեղադրության մասին տվյալների աղբյուրների կառավարման լրացուցիչ հրահանգներ: Սա կարող է ծրագրին թույլ տալ միջամտել GPS-ի կամ տեղադրության մասին տվյալների այլ աղբյուրների գործառույթներին:"</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"Տեղադրության ճշգրիտ տվյալների հասանելիություն միայն ֆոնային ռեժիմում"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Երբ հավելվածն ակտիվ է, այն կարող է տեղորոշման ծառայություններից ստանալ ձեր ճշգրիտ տեղադրության տվյալները։ Որպես նախապայման՝ ձեր սարքի տեղորոշման ծառայությունները պետք է միացված լինեն։ Դա կարող է ավելի արագ սպառել մարտկոցի լիցքը։"</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"տեղադրության մոտավոր տվյալների հասանելիություն միայն ակտիվ ռեժիմում"</string>
@@ -694,7 +694,7 @@
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"փոփոխել կամ ջնջել ձեր ընդհանուր հիշողության բովանդակությունը"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Հավելվածին թույլ է տալիս փոփոխել ձեր ընդհանուր հիշողության պարունակությունը:"</string>
<string name="permlab_use_sip" msgid="8250774565189337477">"կատարել կամ ստանալ SIP զանգեր"</string>
- <string name="permdesc_use_sip" msgid="3590270893253204451">"Ծրագրին թույլ է տալիս կատարել և ստանալ SIP զանգեր:"</string>
+ <string name="permdesc_use_sip" msgid="3590270893253204451">"Հավելվածին թույլ է տալիս կատարել և ստանալ SIP զանգեր:"</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"գրանցել նոր հեռահաղորդակցության SIM կապեր"</string>
<string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Հավելվածին թույլ է տալիս գրանցել հեռահաղորդակցության նոր SIM կապեր:"</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"գրանցել նոր հեռահաղորդակցության կապեր"</string>
@@ -728,11 +728,11 @@
<string name="permlab_setInputCalibration" msgid="932069700285223434">"փոփոխել մուտքի սարքի չափաբերումը"</string>
<string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Թույլ է տալիս ծրագրին փոփոխել հպէկրանի չափաբերման կարգավորումները: Սովորական ծրագրերի համար երբեք պետք չի գալու:"</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"DRM հավաստագրերի մատչում"</string>
- <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Ծրագրին թույլ է տալիս տրամադրել և օգտագործել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
+ <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Հավելվածին թույլ է տալիս տրամադրել և օգտագործել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"ստանալ Android Beam-ով փոխանցման կարգավիճակը"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Ծրագրին թույլ է տալիս ստանալ Android Beam-ով ընթացիկ փոխանցումների մասին տեղեկատվություն:"</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Հավելվածին թույլ է տալիս ստանալ Android Beam-ով ընթացիկ փոխանցումների մասին տեղեկատվություն:"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"հեռացնել DRM վկայագրեր"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Ծրագրին թույլ է տալիս հեռացնել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Հավելվածին թույլ է տալիս հեռացնել DRM վկայագրեր: Սովորական ծրագրերի համար երբեք պետք չի գալիս:"</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"Միացում օպերատորի հաղորդագրությունների ծառայության հետ"</string>
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Թույլ է տալիս տիրոջը կապվել օպերատորի հաղորդագրությունների ծառայության վերին մակարդակի միջերեսի հետ: Սա երբեք չի պահանջվում սովորական հավելվածների համար:"</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"կապվել օպերատորի ծառայություններին"</string>
@@ -1442,7 +1442,7 @@
<string name="permlab_route_media_output" msgid="8048124531439513118">"երթուղել մեդիա արտածումը"</string>
<string name="permdesc_route_media_output" msgid="1759683269387729675">"Թույլ է տալիս հավելվածին մեդիա արտածումը երթուղել այլ արտաքին սարքեր:"</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"կարդալ տեղադրման աշխատաշրջանները"</string>
- <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Ծրագրին թույլ է տալիս կարդալ տեղադրման աշխատաշրջանները: Սա թույլ է տալիս տեղեկանալ փաթեթների ակտիվ տեղադրումների մանրամասներին:"</string>
+ <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Հավելվածին թույլ է տալիս կարդալ տեղադրման աշխատաշրջանները: Սա թույլ է տալիս տեղեկանալ փաթեթների ակտիվ տեղադրումների մանրամասներին:"</string>
<string name="permlab_requestInstallPackages" msgid="7600020863445351154">"պահանջել տեղադրման փաթեթներ"</string>
<string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Թույլ է տալիս հավելվածին պահանջել փաթեթների տեղադրումը:"</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"պահանջել փաթեթների ջնջում"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«Չանհանգստացնել» ռեժիմի կարգավորումները փոխվել են"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Հպեք՝ տեսնելու, թե ինչ է արգելափակվել:"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Ստուգեք ծանուցումների կարգավորումները"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Հավելվածներին, որոնք տեղադրում եք Android 13 և ավելի նոր տարբերակներով սարքերում, անհրաժեշտ է տրամադրել ծանուցումներ ուղարկելու թույլտվություն։ Հպեք և փոխեք այս թույլտվությունն արդեն տեղադրված հավելվածների համար։"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Հիշեցնել ավելի ուշ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Փակել"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Համակարգ"</string>
@@ -2140,7 +2139,7 @@
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Այս բովանդակությունը հնարավոր չէ ուղարկել անձնական հավելվածներով"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Այս բովանդակությունը հնարավոր չէ բացել անձնական հավելվածներով"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"Աշխատանքային պրոֆիլի ծառայությունը դադարեցված է"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"Հպեք՝ միացնելու համար"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"Հպեք միացնելու համար"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Աշխատանքային հավելվածներ չկան"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Անձնական հավելվածներ չկան"</string>
<string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Բացե՞լ <xliff:g id="APP">%s</xliff:g> հավելվածը ձեր անձնական պրոֆիլում"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 0fb0f5b..270aa25 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -56,7 +56,7 @@
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEI"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
- <string name="ClipMmi" msgid="4110549342447630629">"Nomor Penelepon Masuk"</string>
+ <string name="ClipMmi" msgid="4110549342447630629">"ID Penelepon Masuk"</string>
<string name="ClirMmi" msgid="6752346475055446417">"Menyembunyikan ID Penelepon untuk Panggilan Keluar"</string>
<string name="ColpMmi" msgid="4736462893284419302">"ID Saluran yang Terhubung"</string>
<string name="ColrMmi" msgid="5889782479745764278">"Batasan ID Saluran yang Terhubung"</string>
@@ -71,12 +71,12 @@
<string name="RuacMmi" msgid="1876047385848991110">"Penolakan panggilan yang tidak diinginkan"</string>
<string name="CndMmi" msgid="185136449405618437">"Pengiriman nomor panggilan"</string>
<string name="DndMmi" msgid="8797375819689129800">"Jangan ganggu"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Nomor penelepon default \"dibatasi\". Panggilan selanjutnya: Dibatasi"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nomor pengguna default \"dibatasi\". Panggilan selanjutnya: Tidak dibatasi."</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Nomor penelepon default tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"Nomor penelepon default tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID penelepon diatur default ke \"dibatasi\". Panggilan selanjutnya: Dibatasi"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID penelepon diatur default ke \"dibatasi\". Panggilan selanjutnya: Tidak dibatasi."</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID penelepon diatur default ke tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"ID penelepon diatur default ke tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
<string name="serviceNotProvisioned" msgid="8289333510236766193">"Layanan tidak diperlengkapi."</string>
- <string name="CLIRPermanent" msgid="166443681876381118">"Anda tidak dapat mengubah setelan nomor penelepon."</string>
+ <string name="CLIRPermanent" msgid="166443681876381118">"Anda tidak dapat mengubah setelan ID penelepon."</string>
<string name="RestrictedOnDataTitle" msgid="1500576417268169774">"Tidak ada layanan data seluler"</string>
<string name="RestrictedOnEmergencyTitle" msgid="2852916906106191866">"Panggilan darurat tidak tersedia"</string>
<string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Tidak ada layanan panggilan suara"</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalender"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"mengirim dan melihat pesan SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"File & dokumen"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"File dan dokumen"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"mengakses file dan dokumen di perangkat Anda"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik & audio lainnya"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mengakses file audio di perangkat Anda"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto & video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"mengakses file gambar dan video di perangkat Anda"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musik dan audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"mengakses musik dan audio di perangkat Anda"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto dan video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"mengakses foto dan video di perangkat Anda"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"merekam audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktivitas fisik"</string>
@@ -349,7 +349,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Mengizinkan apl memperluas atau menciutkan bilah status."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Tampilkan notifikasi sebagai aktivitas layar penuh di perangkat terkunci"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Mengizinkan aplikasi untuk menampilkan notifikasi sebagai aktivitas layar penuh di perangkat terkunci"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"memasang pintasan"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Memasang pintasan"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Mengizinkan aplikasi menambahkan pintasan Layar Utama tanpa tindakan dari pengguna."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"meng-uninstal pintasan"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Mengizinkan aplikasi menghapus pintasan Layar Utama tanpa tindakan dari pengguna."</string>
@@ -639,12 +639,12 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"Terlalu gelap. Coba pencahayaan yang lebih cerah."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Gerakkan ponsel menjauh."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Gerakkan ponsel mendekat."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"Gerakkan ponsel ke atas."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"Gerakkan ponsel ke bawah."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"Geser ponsel ke atas."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"Geser ponsel ke bawah."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Gerakkan ponsel ke kiri."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Gerakkan ponsel ke kanan."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Lihat langsung ke perangkat."</string>
- <string name="face_acquired_not_detected" msgid="2945945257956443257">"Posisikan wajah Anda langsung di depan ponsel."</string>
+ <string name="face_acquired_not_detected" msgid="2945945257956443257">"Posisikan wajah Anda tepat di depan ponsel."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Terlalu banyak gerakan. Stabilkan ponsel."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Daftarkan ulang wajah Anda."</string>
<string name="face_acquired_too_different" msgid="4699657338753282542">"Tidak lagi dapat mengenali wajah. Coba lagi."</string>
@@ -1015,8 +1015,8 @@
<string name="save_password_label" msgid="9161712335355510035">"Konfirmasi"</string>
<string name="double_tap_toast" msgid="7065519579174882778">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
<string name="autofill_this_form" msgid="3187132440451621492">"Isi Otomatis"</string>
- <string name="setup_autofill" msgid="5431369130866618567">"Siapkan Pengisian Otomatis"</string>
- <string name="autofill_window_title" msgid="4379134104008111961">"IsiOtomatis dengan <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
+ <string name="setup_autofill" msgid="5431369130866618567">"Siapkan Isi otomatis"</string>
+ <string name="autofill_window_title" msgid="4379134104008111961">"Isi otomatis dengan <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
<string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
@@ -1986,10 +1986,10 @@
<string name="time_picker_prompt_label" msgid="303588544656363889">"Ketikkan waktu"</string>
<string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Beralih ke mode masukan teks untuk masukan waktu."</string>
<string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Beralih ke mode jam untuk masukan waktu."</string>
- <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opsi IsiOtomatis"</string>
- <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Simpan untuk IsiOtomatis"</string>
+ <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Opsi isi otomatis"</string>
+ <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Simpan untuk Isi otomatis"</string>
<string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Konten tidak dapat diisi otomatis"</string>
- <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Tidak ada saran IsiOtomatis"</string>
+ <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Tidak ada saran isi otomatis"</string>
<string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{Satu saran isi otomatis}other{# saran isi otomatis}}"</string>
<string name="autofill_save_title" msgid="7719802414283739775">"Simpan ke "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
<string name="autofill_save_title_with_type" msgid="3002460014579799605">"Simpan <xliff:g id="TYPE">%1$s</xliff:g> ke "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Jangan Ganggu telah berubah"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ketuk untuk memeriksa item yang diblokir."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Tinjau setelan notifikasi"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Mulai Android 13, aplikasi yang Anda instal memerlukan izin untuk mengirim notifikasi. Ketuk guna mengubah izin ini untuk aplikasi yang sudah ada."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ingatkan saya nanti"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Tutup"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index ce84af7..fb0bb4f 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"fá aðgang að dagatalinu þínu"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"senda og skoða SMS-skilaboð"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Skrár og skjöl"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Skrár og skjöl"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"fá aðgang að skrám og skjölum í tækinu þínu"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Tónlist og annað hljóð"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fá aðgang að hljóðskrám í tækinu þínu"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Myndir og myndskeið"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"fá aðgang að myndum og myndskeiðaskrám í tækinu þínu"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Tónlist og hljóð"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"fáðu aðgang að tónlist og hljóði í tækinu þínu"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Myndir og myndskeið"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"fáðu aðgang að myndum og myndskeiðum á tækinu þínu"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Hljóðnemi"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"taka upp hljóð"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Hreyfing"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„Ónáðið ekki“ var breytt"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ýttu til að skoða hvað lokað hefur verið á."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Yfirfara tilkynningastillingar"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Frá og með Android 13 þurfa forrit sem þú setur upp heimild frá þér til að senda tilkynningar. Ýttu til að breyta þessari heimild fyrir forrit sem fyrir eru."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Minna mig á seinna"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Hunsa"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Kerfi"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1db6e66..ce79744 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"Possono accedere al calendario"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"Possono inviare e visualizzare SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"File e documenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"File e documenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"Consente di accedere a file e documenti sul tuo dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musica e altro audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Accesso ai file audio sul tuo dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto e video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"Accesso ai file immagine e video sul tuo dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musica e audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"accesso a musica e audio sul tuo dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto e video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"accesso a foto e video sul tuo dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"Possono registrare audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Attività fisica"</string>
@@ -349,8 +349,8 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Consente all\'applicazione di espandere o comprimere la barra di stato."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Visualizzazione di notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Consente all\'app di visualizzare le notifiche sotto forma di attività in modalità a schermo intero su un dispositivo bloccato"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"aggiunta di scorciatoie"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Consente a un\'applicazione di aggiungere scorciatoie alla schermata Home automaticamente."</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Aggiunta di scorciatoie"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"consentire a un\'applicazione di aggiungere scorciatoie alla schermata Home automaticamente"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"eliminazione di scorciatoie"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Consente all\'applicazione di rimuovere le scorciatoie della schermata Home automaticamente."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"reindirizzamento chiamate in uscita"</string>
@@ -1443,7 +1443,7 @@
<string name="permdesc_route_media_output" msgid="1759683269387729675">"Consente a un\'applicazione di indirizzare l\'uscita di media verso altri dispositivi esterni."</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"lettura delle sessioni di installazione"</string>
<string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Consente a un\'applicazione di leggere le sessioni di installazione. L\'app può conoscere i dettagli sulle installazioni di pacchetti attive."</string>
- <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"richiesta di pacchetti di installazione"</string>
+ <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"richiesta di installazione di pacchetti"</string>
<string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Consente a un\'applicazione di richiedere l\'installazione di pacchetti."</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"richiesta di eliminazione dei pacchetti"</string>
<string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Consente a un\'applicazione di richiedere l\'eliminazione di pacchetti."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"L\'impostazione Non disturbare è cambiata"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tocca per controllare le notifiche bloccate."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Controlla le impostazioni di notifica"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"A partire da Android 13, le app che installi devono avere la tua autorizzazione per poter inviare notifiche. Tocca per cambiare questa autorizzazione per le app esistenti."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ricordamelo dopo"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ignora"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0449349..ae749f3 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"גישה אל היומן"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"שליחה והצגה של הודעות SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"קבצים ומסמכים"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"קבצים ומסמכים"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"גישה לקבצים ולמסמכים במכשיר"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"מוזיקה וסוגי אודיו אחרים"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"גישה לקובצי אודיו במכשיר"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"תמונות וסרטונים"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"גישה לקובצי וידאו ותמונה במכשיר"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"מוזיקה ואודיו"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"גישה למוזיקה ולאודיו במכשיר"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"תמונות וסרטונים"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"גישה לתמונות ולסרטונים במכשיר"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"מיקרופון"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"הקלטת אודיו"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"פעילות גופנית"</string>
@@ -352,7 +352,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"הצגת התראות כפעילויות במסך מלא במכשיר נעול"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"מאפשרת לאפליקציה להציג התראות כפעילויות במסך מלא במכשיר נעול"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"התקנה של קיצורי דרך"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשרת לאפליקציה להוסיף קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"מאפשרת לאפליקציה להוסיף קיצורי דרך במסך הבית ללא התערבות המשתמש."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"הסרת התקנה של קיצורי דרך"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"מאפשרת לאפליקציה להסיר קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"ניתוב מחדש של שיחות יוצאות"</string>
@@ -587,11 +587,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"שגיאה באימות"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"יש לבטל את נעילת המסך כדי להמשיך"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"צריך ללחוץ חזק על החיישן"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"לוחצים לחיצה חזקה על החיישן"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. אפשר לנסות שוב."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"עליך לנקות את חיישן טביעות האצבע ולנסות שוב"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"עליך לנקות את החיישן ולנסות שוב"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"צריך ללחוץ חזק על החיישן"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"לוחצים לחיצה חזקה על החיישן"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"הזזת את האצבע לאט מדי. יש לנסות שוב."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"יש להשתמש בטביעת אצבע אחרת"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"בהיר מדי"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ההגדרה \'נא לא להפריע\' השתנתה"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"יש להקיש כדי לבדוק מה חסום."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"בדיקת הגדרת ההתראות"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"החל מגרסת Android 13, אפליקציות שיותקנו יוכלו לשלוח התראות רק אם יקבלו ממך הרשאה. אפשר להקיש כדי לשנות את ההרשאה הזו באפליקציות קיימות."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"תזכירו לי מאוחר יותר"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"סגירה"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"מערכת"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 1fe3736..84cb4b9 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"カレンダーへのアクセス"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMSメッセージの送信と表示"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ファイル、ドキュメント"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ファイルとドキュメント"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"デバイス内のファイルやドキュメントへのアクセス"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音楽やその他の音声"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"デバイス上の音声ファイルへのアクセス"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"写真と動画"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"デバイス上の画像、動画ファイルへのアクセス"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"音楽とオーディオ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"デバイス上の音楽とオーディオにアクセスする"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"写真と動画"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"デバイス上の写真と動画にアクセスする"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"マイク"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"音声の録音"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"身体活動"</string>
@@ -639,8 +639,8 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"暗すぎます。もっと明るい場所でお試しください。"</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"スマートフォンをもっと離してください。"</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"スマートフォンをもっと近づけてください。"</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"スマートフォンをもっと高い位置に上げてください。"</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"スマートフォンをもっと低い位置に下げてください。"</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"スマートフォンを上に動かしてください。"</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"スマートフォンを下に動かしてください。"</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"スマートフォンを左に動かしてください。"</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"スマートフォンを右に動かしてください。"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"もっとまっすぐデバイスに顔を向けてください。"</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>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"サイレント モードが変わりました"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"タップしてブロック対象をご確認ください。"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"通知設定の確認"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 以降では、インストールするアプリに、通知を送信する権限を付与する必要があります。既存のアプリのこの権限を変更するには、タップしてください。"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"後で"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"閉じる"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"システム"</string>
@@ -2140,7 +2139,7 @@
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"このコンテンツを個人用アプリと共有することはできません"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"このコンテンツを個人用アプリで開くことはできません"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"仕事用プロファイルが一時停止しています"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"タップすると有効になります"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"タップして有効化"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"仕事用アプリはありません"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"個人用アプリはありません"</string>
<string name="miniresolver_open_in_personal" msgid="3874522693661065566">"個人用プロファイルで <xliff:g id="APP">%s</xliff:g> を開きますか?"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 7fb4833..45557f0 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"თქვენს კალენდარზე წვდომა"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS შეტყობინებების გაგზავნა და ნახვა"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ფაილები და დოკუმენტები"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ფაილები და დოკუმენტები"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"თქვენს მოწყობილობაზე ფაილებსა და დოკუმენტებზე წვდომა"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"მუსიკა და სხვა აუდიო ფაილები"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"თქვენს მოწყობილობაზე აუდიო ფაილებზე წვდომა"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ფოტოები და ვიდეოები"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"თქვენს მოწყობილობაზე სურათის ფაილებსა და ვიდეო ფაილებზე წვდომა"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"მუსიკა და აუდიო"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"იქონიეთ წვდომა მუსიკასა და აუდიოზე თქვენს მოწყობილობაზე"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ფოტოები და ვიდეოები"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"იქონიეთ წვდომა ფოტოებსა და ვიდეოებზე თქვენს მოწყობილობაზე"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"მიკროფონი"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"აუდიოს ჩაწერა"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ფიზიკური აქტივობა"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„არ შემაწუხოთ“ რეჟიმი შეცვლილია"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"შეეხეთ იმის სანახავად, თუ რა არის დაბლოკილი."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"შეტყობინების პარამეტრების შემოწმება"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13-ზე შეტყობინებების გასაგზავნად საჭიროა თქვენ მიერ დაინსტალირებული აპებისთვის ნებართვის მინიჭება. არსებული აპებისთვის ამ ნებართვის შესაცვლელად შეეხეთ."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"შემახსენე მოგვიან."</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"უარყოფა"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"სისტემა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 4bd7c14..abec1a6 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -305,16 +305,16 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"күнтізбеге кіру"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS хабарларын жіберу және көру"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар мен құжаттар"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файлдар мен құжаттар"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"құрылғыдағы файлдар мен құжаттарды пайдалану"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка және басқа аудио"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"құрылғыдағы аудиофайлдарды пайдалану"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотосуреттер және бейнелер"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"құрылғыдағы кескіндер мен бейнефайлдарды пайдалану"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музыка және аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"құрылғыдағы музыка мен аудиомазмұнды пайдалану рұқсаты"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Фотосуреттер мен бейнелер"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"құрылғыдағы фотосуреттер мен бейнелерді пайдалану рұқсаты"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жазу"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Іс-қимыл"</string>
- <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"іс-қимыл дерегін алу"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Қимыл-қозғалыс"</string>
+ <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"қимыл-қозғалыс дерегін алу"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Камера"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"суретке түсіріп, бейне жазу"</string>
<string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Маңайдағы құрылғылар"</string>
@@ -350,9 +350,9 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсету"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Қолданбаның құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсетуіне рұқсат береді."</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"таңбаша орнату"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Қолданбаға Негізгі экранның төте пернелерін пайдаланушының қатысуынсыз қосу мүмкіндігін береді."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Қолданбаға Негізгі экранға таңбашаларды пайдаланушының қатысуынсыз қосу мүмкіндігін береді."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"төте пернелерді алып тастау"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Қолданбаға Негізгі экранның төте пернелерін пайдаланушының қатысуынсыз алып тастау мүмкіндігін береді."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Қолданбаға Негізгі экрандағы таңбашаларды пайдаланушының қатысуынсыз өшіру мүмкіндігін береді."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"шығыс қоңырауларды қайта бағыттау"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Қолданбаға шығыс қоңырау кезінде қоңырауды басқа нөмірге қайта бағыттау немесе қоңырауды мүлде доғару опциясы бар теріліп жатқан нөмірді көруге рұқсат береді."</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"телефон қоңырауларына жауап беру"</string>
@@ -589,7 +589,7 @@
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Саусақ ізін оқу сканерін тазалап, әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сканерді тазалап, әрекетті қайталаңыз."</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерге қатты басыңыз."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерді қатты басыңыз."</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Саусағыңызды тым баяу қозғалттыңыз. Әрекетті қайталап көріңіз."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Мазаламау режимі өзгерді"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Түймені түртіп, неге тыйым салынатынын көріңіз."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Хабарландыру параметрлерін қарау"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 нұсқасынан бастап орнатылатын қолданбалар үшін хабарландыру жіберу рұқсаты керек. Бұрынғы қолданбаларда осы рұқсатты өзгерту үшін түртіңіз."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Кейінірек еске салу"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Жабу"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Жүйе"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a344709..9859bf2 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"សារ SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"ផ្ញើ និងមើលសារ SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ឯកសារ"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ឯកសារ"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ចូលប្រើឯកសារនៅលើឧបករណ៍របស់អ្នក"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"តន្ត្រី និងសំឡេងផ្សេងទៀត"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ចូលប្រើឯកសារសំឡេងនៅលើឧបករណ៍របស់អ្នក"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"រូបថត និងវីដេអូ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ចូលប្រើឯកសាររូបភាព និងវីដេអូនៅលើឧបករណ៍របស់អ្នក"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"តន្រ្តី និងសំឡេង"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ចូលប្រើតន្ត្រី និងសំឡេងនៅលើឧបករណ៍របស់អ្នក"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"រូបថត និងវីដេអូ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ចូលប្រើរូបថត និងវីដេអូនៅលើឧបករណ៍របស់អ្នក"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"មីក្រូហ្វូន"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ថតសំឡេង"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"សកម្មភាពរាងកាយ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"មុខងារកុំរំខានត្រូវបានប្ដូរ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"សូមចុចដើម្បីមើលថាបានទប់ស្កាត់អ្វីខ្លះ។"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ពិនិត្យមើលការកំណត់ការជូនដំណឹង"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"ចាប់ពី Android 13 ឡើងទៅ កម្មវិធីដែលអ្នកដំឡើងត្រូវការការអនុញ្ញាតរបស់អ្នក ដើម្បីផ្ញើការជូនដំណឹង។ សូមចុចដើម្បីផ្លាស់ប្ដូរការអនុញ្ញាតនេះសម្រាប់កម្មវិធីដែលមានស្រាប់។"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"រំលឹកខ្ញុំពេលក្រោយ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ច្រានចោល"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ប្រព័ន្ធ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index eb1baf0..deaa124 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ನಿರ್ವಹಿಸಲು"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ಫೈಲ್ಗಳು ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ಫೈಲ್ಗಳು ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಫೈಲ್ಗಳು ಮತ್ತು ಡಾಕ್ಯುಮೆಂಟ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ಸಂಗೀತ ಮತ್ತು ಇತರ ಆಡಿಯೋ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊ ಫೈಲ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"ಸಂಗೀತ ಮತ್ತು ಆಡಿಯೋ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಂಗೀತ ಮತ್ತು ಆಡಿಯೊವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ಮೈಕ್ರೋಫೋನ್"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ದೈಹಿಕ ಚಟುವಟಿಕೆ"</string>
@@ -1012,7 +1012,7 @@
<string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"ಈ ಪುಟದಿಂದ ಹೊರಬನ್ನಿ"</string>
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ಈ ಪುಟದಲ್ಲಿಯೇ ಇರಿ"</string>
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nನೀವು ಈ ಪುಟದಿಂದಾಚೆಗೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಲು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?"</string>
- <string name="save_password_label" msgid="9161712335355510035">"ದೃಢೀಕರಿಸು"</string>
+ <string name="save_password_label" msgid="9161712335355510035">"ದೃಢೀಕರಿಸಿ"</string>
<string name="double_tap_toast" msgid="7065519579174882778">"ಸಲಹೆ: ಝೂಮ್ ಇನ್ ಮತ್ತು ಝೂಮ್ ಔಟ್ ಮಾಡಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="autofill_this_form" msgid="3187132440451621492">"ಸ್ವಯಂತುಂಬುವಿಕೆ"</string>
<string name="setup_autofill" msgid="5431369130866618567">"ಸ್ವಯಂತುಂಬುವಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಬದಲಾಗಿದೆ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ಏನನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 ನಿಂದ ಪ್ರಾರಂಭಿಸಿ, ನೀವು ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವ ಆ್ಯಪ್ಗಳಿಗೆ, ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮ್ಮ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ. ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಆ್ಯಪ್ಗಳಿಗಾಗಿ ಈ ಅನುಮತಿಯನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ನಂತರ ರಿಮೈಂಡ್ ಮಾಡಿ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ವಜಾಗೊಳಿಸಿ"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ಸಿಸ್ಟಂ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f8b9bdc..6d26efd 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"캘린더에 액세스"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS 메시지 전송 및 보기"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"파일 및 문서"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"파일 및 문서"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"기기의 파일 및 문서에 액세스"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"음악 및 기타 오디오"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"기기에 있는 오디오 파일에 액세스"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"사진 및 동영상"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"기기에 있는 이미지 및 동영상 파일에 액세스"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"음악 및 오디오"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"기기의 음악 및 오디오에 액세스"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"사진 및 동영상"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"기기의 사진 및 동영상에 액세스"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"마이크"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"오디오 녹음"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"신체 활동"</string>
@@ -594,7 +594,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"조정 시도"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요."</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"지문이 인식되지 않습니다."</string>
@@ -640,7 +640,7 @@
<string name="face_acquired_too_close" msgid="1628767882971469833">"휴대전화를 더 멀리 위치시키세요."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"휴대전화를 더 가깝게 위치시키세요."</string>
<string name="face_acquired_too_high" msgid="4868033653626081839">"휴대전화를 위쪽으로 이동하세요."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"휴대전화를 아래쪽으로 이동하세요."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"휴대전화를 아래로 이동하세요"</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"휴대전화를 왼쪽으로 이동하세요."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"휴대전화를 오른쪽으로 이동하세요."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"기기에서 더 똑바로 바라보세요."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"방해 금지 모드 변경"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"차단된 항목을 확인하려면 탭하세요."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"알림 설정 검토"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13부터 설치된 앱에는 알림을 전송하기 위한 권한이 필요합니다. 기존 앱의 알림 전송 권한을 변경하려면 탭하세요."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"나중에 알림"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"닫기"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"시스템"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 663842f..f7c4ca3 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -47,7 +47,7 @@
<string name="mismatchPin" msgid="2929611853228707473">"Терилген PIN\'дер дал келбейт."</string>
<string name="invalidPin" msgid="7542498253319440408">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
<string name="invalidPuk" msgid="8831151490931907083">"Узундугу 8 же көбүрөөк сандан турган PUK-кодду териңиз."</string>
- <string name="needPuk" msgid="7321876090152422918">"SIM картаңыз PUK менен кулпуланган. Кулпусун ачуу үчүн, PUK-кодду териңиз."</string>
+ <string name="needPuk" msgid="7321876090152422918">"SIM картаңыз PUK менен кулпуланган. Кулпусун ачуу үчүн PUK-кодду териңиз."</string>
<string name="needPuk2" msgid="7032612093451537186">"SIM картаны бөгөттөн чыгаруу үчүн PUK2 кодун териңиз."</string>
<string name="enablePin" msgid="2543771964137091212">"Оңунан чыкпады, SIM/RUIM бөгөттөөсүн жандырыңыз."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"жылнаамаңызды пайдалануу"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар жана документтер"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файлдар жана документтер"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"түзмөгүңүздөгү файлдары жана документтерди колдонуу"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка жана башка аудио"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"түзмөгүңүздөгү аудио файлдарга мүмкүнчүлүк алуу"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Сүрөттөр жана видеолор"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"түзмөгүңүздөгү сүрөттөр менен видеолорго мүмкүнчүлүк алуу"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музыка жана аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"түзмөгүңүздөгү музыка менен аудиолорго мүмкүнчүлүк алуу"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Сүрөттөр жана видеолор"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"түзмөгүңүздөгү сүрөттөр менен видеолорго мүмкүнчүлүк алуу"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"аудио жаздыруу"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Кыймыл-аракет"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүү"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Колдонмого билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүүгө уруксат берет"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Ыкчам баскыч түзүү"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмого үй экранга колдонуучунун катышуусусуз тез чакырма кошууга мүмкүнчүлүк берет."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмо башкы экранга ыкчам баскычтарды өз алдынча кошо алат"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"тез чакыргычтарды жок кылуу"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Колдонмого колдонуучунун катышуусусуз үй экранынын тез чакырмаларын жок кылуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"чыгыш чалууларды кайра багыттоо"</string>
@@ -639,7 +639,7 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Телефонду алысыраак жылдырыңыз."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Телефонду жакыныраак жылдырыңыз."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"Телефонду жогору жылдырыңыз."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"Телефонду өйдө жылдырыңыз."</string>
<string name="face_acquired_too_low" msgid="1512237819632165945">"Телефонду ылдый жылдырыңыз."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Телефонду солго жылдырыңыз."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Телефонду оңго жылдырыңыз."</string>
@@ -905,13 +905,13 @@
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Кулпуну ачуу үчүн сырсөздү териңиз"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Кулпуну ачуу үчүн PIN кодду териңиз"</string>
<string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN-код туура эмес."</string>
- <string name="keyguard_label_text" msgid="3841953694564168384">"Кулпусун ачуу үчүн, Менюна андан соң 0 баскычын басыңыз."</string>
+ <string name="keyguard_label_text" msgid="3841953694564168384">"Кулпусун ачуу үчүн Менюну андан соң 0 баскычын басыңыз."</string>
<string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Өзгөчө кырдаалдар кызматы"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"Интернет жок"</string>
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"Экран кулпуланды."</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Кулпусун ачып же Шашылыш чалуу аткаруу үчүн менюну басыңыз."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Бөгөттөн чыгаруу үчүн Менюну басыңыз."</string>
- <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Кулпуну ачуу үчүн, үлгүнү тартыңыз"</string>
+ <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Кулпуну ачуу үчүн үлгүнү тартыңыз"</string>
<string name="lockscreen_emergency_call" msgid="7500692654885445299">"Шашылыш чалуу"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Чалууга кайтуу"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Туура!"</string>
@@ -1384,7 +1384,7 @@
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тил жана калып тандоо үчүн таптап коюңуз"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Башка терезелердин үстүнөн көрсөтүү"</string>
+ <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Башка колдонмолордун үстүнөн көрсөтүү"</string>
<string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> колдонмосун башка терезелердин үстүнөн көрсөтүү"</string>
<string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g>: башка колдонмолордун үстүнөн"</string>
<string name="alert_windows_notification_message" msgid="6538171456970725333">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Тынчымды алба\" режими өзгөрдү"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Билдирмелердин жөндөөлөрүн карап чыгуу"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 версиясынан баштап билдирмелерди жөнөтүү үчүн орноткон колдонмолоруңузга уруксат берүү керек. Учурдагы колдонмолор үчүн бул уруксатты өзгөртүү үчүн таптап коюңуз."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Кийинчерээк эскертүү"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Жабуу"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Тутум"</string>
@@ -2104,7 +2103,7 @@
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # файл}other{{file_name} + # файл}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Бөлүшкөнгө эч ким сунушталган жок"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Колдонмолордун тизмеси"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Бул колдонмонун жаздырууга уруксаты жок, бирок бул USB түзмөгү аркылуу аудиону жаздыра алат."</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Бул колдонмого жаздырууга уруксат берилген эмес, бирок ушул USB түзмөгү аркылуу үндөрдү жаза алат."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Башкы бет"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Артка"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Акыркы колдонмолор"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9e8b119..06920ba 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ເຂົ້າຫາປະຕິທິນຂອງທ່ານ"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"ສົ່ງ ແລະເບິ່ງຂໍ້ຄວາມ SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ໄຟລ໌ ແລະ ເອກະສານ"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ໄຟລ໌ ແລະ ເອກະສານ"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ເຂົ້າເຖິງໄຟລ໌ ແລະ ເອກະສານຢູ່ອຸປະກອນຂອງທ່ານ"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ເພງ ແລະ ສຽງອື່ນໆ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ເຂົ້າເຖິງໄຟລ໌ສຽງຢູ່ອຸປະກອນຂອງທ່ານ"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ຮູບພາບ ແລະ ວິດີໂອ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ເຂົ້າເຖິງໄຟລ໌ຮູບ ແລະ ວິດີໂອຢູ່ອຸປະກອນຂອງທ່ານ"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"ເພງ ແລະ ສຽງ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ເຂົ້າເຖິງເພງ ແລະ ສຽງຢູ່ອຸປະກອນຂອງທ່ານ"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ຮູບພາບ ແລະ ວິດີໂອ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ເຂົ້າເຖິງຮູບພາບ ແລະ ວິດີໂອຢູ່ອຸປະກອນຂອງທ່ານ"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ໄມໂຄຣໂຟນ"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ບັນທຶກສຽງ"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ກິດຈະກຳທາງກາຍະພາບ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ປ່ຽນໂໝດຫ້າມລົບກວນແລ້ວ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ແຕະເພື່ອກວດສອບວ່າມີຫຍັງຖືກບລັອກໄວ້ແດ່."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ກວດສອບການຕັ້ງຄ່າການແຈ້ງເຕືອນ"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"ເລີ່ມຕົ້ນໃນ Android 13, ແອັບຕ່າງໆທີ່ທ່ານຕິດຕັ້ງຈະຕ້ອງໃຊ້ການອະນຸຍາດຂອງທ່ານເພື່ອສົ່ງການແຈ້ງເຕືອນ. ແຕະເພື່ອປ່ຽນການອະນຸຍາດນີ້ສຳລັບແອັບທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ແຈ້ງເຕືອນຂ້ອຍພາຍຫຼັງ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ປິດໄວ້"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ລະບົບ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 989d57c..22d57d8 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"pasiekti kalendorių"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"siųsti ir peržiūrėti SMS pranešimus"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Failai ir dokumentai"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Failai ir dokumentai"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"pasiekti failus ir dokumentus jūsų įrenginyje"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika ir kiti garso įrašai"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pasiekti garso failus įrenginyje"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Nuotraukos ir vaizdo įrašai"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"pasiekti vaizdo ir vaizdo įrašo failus įrenginyje"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika ir garso įrašai"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"pasiekti muziką ir garso įrašus jūsų įrenginyje"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Nuotraukos ir vaizdo įrašai"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pasiekti nuotraukas ir vaizdo įrašus jūsų įrenginyje"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonas"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"įrašyti garso įrašą"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fizinė veikla"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Netrukdymo režimas pakeistas"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Palieskite, kad patikrintumėte, kas blokuojama."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Peržiūrėkite pranešimų nustatymus"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Tryliktos ir naujesnių versijų „Android” jūsų įdiegtoms programoms reikia suteikti leidimą siųsti pranešimus. Palieskite, kad pakeistumėte šį leidimą esamoms programoms."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Priminti vėliau"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Atsisakyti"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 076900c..3b96a07 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"piekļūt jūsu kalendāram"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Īsziņas"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"sūtīt un skatīt īsziņas"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili un dokumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Faili un dokumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"piekļuve failiem un dokumentiem jūsu ierīcē"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Mūzika un cits audio saturs"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"piekļūt audio failiem jūsu ierīcē"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoattēli un videoklipi"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"piekļūt attēlu un video failiem jūsu ierīcē"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Mūzika un audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"piekļuve mūzikai un audio jūsu ierīcē"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotoattēli un videoklipi"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"piekļuve fotoattēliem un videoklipiem jūsu ierīcē"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofons"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ierakstīt audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziskās aktivitātes"</string>
@@ -1671,10 +1671,10 @@
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad īsinājumtaustiņš ir ieslēgts, nospiežot abas skaļuma pogas un 3 sekundes turot tās, tiks aktivizēta pieejamības funkcija."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vai ieslēgt pieejamības funkciju saīsni?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Turot nospiestus abus skaļuma taustiņus dažas sekundes, tiek ieslēgtas pieejamības funkcijas. Tas var mainīt ierīces darbību.\n\nPašreizējās funkcijas:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAtlasītās funkcijas varat mainīt šeit: Iestatījumi > Pieejamība."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Turot nospiestas abas skaļuma pogas dažas sekundes, tiek ieslēgtas pieejamības funkcijas. Tas var mainīt ierīces darbību.\n\nPašreizējās funkcijas:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAtlasītās funkcijas varat mainīt šeit: Iestatījumi > Pieejamība."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Vai ieslēgt <xliff:g id="SERVICE">%1$s</xliff:g> saīsni?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Turot nospiestus abus skaļuma taustiņus dažas sekundes, tiek ieslēgta pieejamības funkcija <xliff:g id="SERVICE">%1$s</xliff:g>. Tas var mainīt ierīces darbību.\n\nŠo saīsni uz citu funkciju varat mainīt šeit: Iestatījumi > Pieejamība."</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Turot nospiestas abas skaļuma pogas dažas sekundes, tiek ieslēgta pieejamības funkcija <xliff:g id="SERVICE">%1$s</xliff:g>. Tas var mainīt ierīces darbību.\n\nŠo saīsni uz citu funkciju varat mainīt šeit: Iestatījumi > Pieejamība."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Ieslēgt"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Neieslēgt"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IESLĒGTA"</string>
@@ -1701,7 +1701,7 @@
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
- <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
+ <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma pogas un turiet tos trīs sekundes."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pieejamības pogai."</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režīms “Netraucēt” ir mainīts"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Pieskarieties, lai uzzinātu, kas tiek bloķēts."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Pārskatīt paziņojumu iestatījumus"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Operētājsistēmā Android 13 un jaunākās versijās jūsu instalētajām lietotnēm ir nepieciešama atļauja sūtīt paziņojumus. Pieskarieties, lai mainītu šo atļauju esošajām lietotnēm."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Atgādināt vēlāk"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Noraidīt"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistēma"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 1c4b514..b0983d32 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"пристапува до календарот"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"испраќа и прикажува SMS-пораки"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Датотеки и документи"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Датотеки и документи"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"да пристапува до датотеки и документи на уредот"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудио"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да пристапува до аудиодатотеки на вашиот уред"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотографии и видеа"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"да пристапува до слики и видеодатотеки на вашиот уред"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика и аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"пристапувајте до музика и аудио на вашиот уред"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Фотографии и видеа"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"пристапувајте до фотографии и видеа на вашиот уред"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима аудио"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичка активност"</string>
@@ -349,10 +349,10 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволува апликацијата да ја прошири или собере статусната лента."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"да прикажува известувања како активности на цел екран на заклучен уред"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дозволува апликацијата да прикажува известувања како активности на цел екран на заклучен уред"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирај кратенки"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Овозможува апликацијата да додава кратенки до почетниот екран без интервенција на корисникот."</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирање кратенки"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Овозможува апликацијата да додава кратенки на почетниот екран без интервенција на корисникот."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирај кратенки"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Овозможува апликацијата да отстранува кратенки до почетниот екран без интервенција на корисникот."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Овозможува апликацијата да отстранува кратенки од почетниот екран без интервенција на корисникот."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"пренасочи појдовни повици"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Дозволува апликацијата да го види бројот што се повикува за време на појдовен повик, со опција да го пренасочи повикот кон друг број или да го прекине повикот."</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"одговара телефонски повици"</string>
@@ -1844,7 +1844,7 @@
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трета деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Побарај PIN пред откачување"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Прашај за лозинка пред откачување"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"Инсталирано од администраторот"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирано од администраторот"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Поставките за „Не вознемирувај“ се изменија"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Допрете за да проверите што е блокирано."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте ги поставките за известувања"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Почнувајќи од Android 13, на апликациите што ги инсталирате им е потребна ваша дозвола за испраќање известувања. Допрете за да ја промените оваа дозвола за постојни апликации."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Потсети ме подоцна"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Отфрли"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
@@ -2134,7 +2133,7 @@
<string name="resolver_work_tab" msgid="2690019516263167035">"За работа"</string>
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Личен приказ"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Работен приказ"</string>
- <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Блокирано од вашиот IT-администратор"</string>
+ <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Блокирано од IT-администраторот"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Овие содржини не може да се споделуваат со работни апликации"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Овие содржини не може да се отвораат со работни апликации"</string>
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Овие содржини не може да се споделуваат со лични апликации"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 9169e97..7dbf02a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS സന്ദേശങ്ങൾ അയയ്ക്കുകയും കാണുകയും ചെയ്യുക"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ഫയലുകളും ഡോക്യുമെന്റുകളും"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ഫയലുകളും ഡോക്യുമെന്റുകളും"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഫയലുകളും ഡോക്യുമെന്റുകളും ആക്സസ് ചെയ്യുക"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"സംഗീതവും മറ്റ് ഓഡിയോയും"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"നിങ്ങളുടെ ഉപകരണത്തിലെ ഓഡിയോ ഫയലുകൾ ആക്സസ് ചെയ്യുക"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ഫോട്ടോകളും വീഡിയോകളും"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"നിങ്ങളുടെ ഉപകരണത്തിലെ വീഡിയോ ഫയലുകൾ ആക്സസ് ചെയ്യുക"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"സംഗീതവും ഓഡിയോയും"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"നിങ്ങളുടെ ഉപകരണത്തിൽ സംഗീതവും ഓഡിയോയും ആക്സസ് ചെയ്യുക"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ഫോട്ടോകളും വീഡിയോകളും"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഫോട്ടോകളും വീഡിയോകളും ആക്സസ് ചെയ്യുക"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"മൈക്രോഫോണ്"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ശാരീരിക ആക്റ്റിവിറ്റി"</string>
@@ -639,7 +639,7 @@
<string name="face_acquired_too_dark" msgid="252573548464426546">"വളരെ ഇരുണ്ടത്. തിളക്കമേറിയ ലൈറ്റിംഗ് പരീക്ഷിക്കുക."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"ഫോൺ കൂടുതൽ അകലേയ്ക്ക് നീക്കുക."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"ഫോൺ അടുത്തേക്ക് നീക്കുക."</string>
- <string name="face_acquired_too_high" msgid="4868033653626081839">"ഫോൺ കൂടുതൽ ഉയരത്തിലേക്ക് നീക്കുക."</string>
+ <string name="face_acquired_too_high" msgid="4868033653626081839">"ഫോൺ മുകളിലേക്ക് ഉയർത്തുക"</string>
<string name="face_acquired_too_low" msgid="1512237819632165945">"ഫോൺ കൂടുതൽ താഴേക്ക് നീക്കുക."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"ഫോൺ ഇടത്തോട്ട് നീക്കുക."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"ഫോൺ വലത്തോട്ട് നീക്കുക."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"അറിയിപ്പ് ക്രമീകരണം അവലോകനം ചെയ്യുക"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 മുതൽ, നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യുന്ന ആപ്പുകൾക്ക് അറിയിപ്പുകൾ അയയ്ക്കാൻ നിങ്ങളുടെ അനുമതി വേണം. നിലവിലുള്ള ആപ്പുകൾക്ക് ഈ അനുമതി മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"പിന്നീട് ഓർമ്മിപ്പിക്കൂ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ഡിസ്മിസ് ചെയ്യുക"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"സിസ്റ്റം"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 9ee9ad1..41eeb7b 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарь руу хандах"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Мессеж"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS мессежийг илгээх, харах"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файл болон документ"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файл, документ"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"таны төхөөрөмж дээрх файл болон документод хандах"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Хөгжим, бусад аудио"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"таны төхөөрөмж дээрх аудио файлд хандах"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Зураг, видео"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"таны төхөөрөмж дээрх зураг болон видео файлд хандах"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Хөгжим, аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"төхөөрөмж дээрээ хөгжим болон аудионд хандах"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Зураг, видео"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"төхөөрөмж дээрээ зураг болон видеонд хандах"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"дуу хураах"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Дасгал хөдөлгөөн"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"мэдэгдлийг түгжигдсэн төхөөрөмж дээр бүтэн дэлгэцийн үйл ажиллагаа байдлаар үзүүлэх"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Аппад мэдэгдлийг түгжигдсэн төхөөрөмж дээр бүтэн дэлгэцийн үйл ажиллагаа байдлаар үзүүлэхийг зөвшөөрдөг"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"товчлол суулгах"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Аппликейшн нь хэрэглэгчийн оролцоогүйгээр Нүүр дэлгэцний товчлолыг нэмж чадна."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Аппликейшн нь хэрэглэгчийн оролцоогүйгээр Үндсэн нүүрний товчлолыг нэмж чадна."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"товчлолыг устгах"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Аппликейшн нь хэрэглэгчийн оролцоогүйгээр Нүүр дэлгэцний товчлолыг устгаж чадна."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"гарсан дуудлагыг чиглэлийг өөрчлөх"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Бүү саад бол горимыг өөрчилсөн"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Блоклосон зүйлийг шалгахын тулд товшино уу."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Мэдэгдлийн тохиргоог шалгах"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13-аас эхлэн таны суулгасан аппууд мэдэгдэл илгээхийн тулд танаас зөвшөөрөл авах шаардлагатай. Одоо байгаа аппуудын уг зөвшөөрлийг өөрчлөхийн тулд товшино уу."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Надад дараа сануул"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Хаах"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 637342d..8325473 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"आपल्या कॅलेंडरवर प्रवेश"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS मेसेज पाठवणे आणि पाहणे हे"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"फाइल आणि दस्तऐवज"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"फाइल आणि दस्तऐवज"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"तुमच्या डिव्हाइसवर फाइल आणि दस्तऐवज अॅक्सेस करा"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"संगीत & इतर ऑडिओ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"तुमच्या डिव्हाइसवर ऑडिओ फाइल अॅक्सेस करा"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फोटो & व्हिडिओ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"तुमच्या डिव्हाइसवर इमेज आणि व्हिडिओ फाइल ॲक्सेस करा"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत आणि ऑडिओ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"तुमच्या डिव्हाइसवर संगीत आणि ऑडिओ अॅक्सेस करा"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फोटो आणि व्हिडिओ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"तुमच्या डिव्हाइसवर फोटो आणि व्हिडिओ अॅक्सेस करा"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"मायक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ऑडिओ रेकॉर्ड"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक अॅक्टिव्हिटी"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करणे"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करण्यासाठी ॲपला अनुमती द्या"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट इंस्टॉल करा"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"अनुप्रयोगाला वापरकर्ता हस्तक्षेपाशिवाय मुख्यस्क्रीन शॉर्टकट जोडण्याची अनुमती देते."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ॲप्लिकेशनला वापरकर्ता हस्तक्षेपाशिवाय मुख्यस्क्रीन शॉर्टकट जोडण्याची अनुमती देते"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट विस्थापित करा"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"अनुप्रयोगाला वापरकर्ता हस्तक्षेपाशिवाय मुख्यस्क्रीन शॉर्टकट काढण्याची अनुमती देते."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"केले जाणारे कॉल पुन्हा मार्गस्थ करा"</string>
@@ -401,7 +401,7 @@
<string name="permdesc_foregroundService" msgid="8720071450020922795">"अॅपला पृष्ठभाग सेवा वापरण्याची अनुमती देते."</string>
<string name="permlab_getPackageSize" msgid="375391550792886641">"अॅप संचयन स्थान मोजा"</string>
<string name="permdesc_getPackageSize" msgid="742743530909966782">"अॅप ला त्याचा कोड, डेटा आणि कॅशे आकार पुनर्प्राप्त करण्यासाठी अनुमती देते"</string>
- <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टम सेटिंग्ज सुधारित करा"</string>
+ <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टीम सेटिंग्ज सुधारित करा"</string>
<string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अॅप ला अनुमती देते. दुर्भावनापूर्ण अॅप्स आपल्या सिस्टीमचे कॉंफिगरेशन दूषित करू शकतात."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"सुरूवातीस चालवा"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टम बूट करणे समाप्त करते तसे अॅप ला स्वतः सुरू करण्यास अनुमती देते. यामुळे टॅबलेट सुरू करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर टॅबलेटला धीमे करण्यास अॅप ला अनुमती देते."</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"व्यत्यय आणू नका बदलले आहे"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"काय ब्लॉक केले आहे हे तपासण्यासाठी टॅप करा."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"सूचना सेटिंग्जचे पुनरावलोकन करा"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 पासून, तुम्ही त्यामध्ये इंस्टॉल केलेल्या अॅप्सना सूचना पाठवण्यासाठी तुमच्या परवानगीची आवश्यकता आहे. सध्याच्या अॅप्ससाठी ही परवानगी बदलण्याकरिता टॅप करा."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"मला आठवण करून द्या"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"डिसमिस करा"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टम"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 487fc1d..cc4aabe 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -297,7 +297,7 @@
<string name="android_system_label" msgid="5974767339591067210">"Sistem Android"</string>
<string name="user_owner_label" msgid="8628726904184471211">"Beralih ke profil peribadi"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"Beralih ke profil kerja"</string>
- <string name="permgrouplab_contacts" msgid="4254143639307316920">"Kenalan"</string>
+ <string name="permgrouplab_contacts" msgid="4254143639307316920">"Contacts"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"mengakses kenalan anda"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"Lokasi"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"mengakses lokasi peranti ini"</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalendar"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"menghantar dan melihat mesej SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fail & dokumen"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fail dan dokumen"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"akses fail dan dokumen pada peranti anda"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzik & audio lain"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"berikan akses fail audio pada peranti anda"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto & video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"berikan akses imej dan fail video pada peranti anda"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzik dan audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"akses muzik dan audio pada peranti anda"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto dan video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"akses foto dan video pada peranti anda"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"rakam audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktiviti fizikal"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Jangan Ganggu telah berubah"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ketik untuk menyemak item yang disekat."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Semak tetapan pemberitahuan"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Bermula dengan Android 13, apl yang anda pasang memerlukan kebenaran anda untuk menghantar pemberitahuan. Ketik untuk menukar kebenaran ini bagi apl sedia ada."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ingatkan saya nanti"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ketepikan"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 78cdb62..fc1495d 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -248,7 +248,7 @@
<string name="global_action_bug_report" msgid="5127867163044170003">"အမှားရှာပြင် မှတ်တမ်း"</string>
<string name="global_action_logout" msgid="6093581310002476511">"စက်ရှင် ပြီးဆုံးပြီ"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"ချွတ်ယွင်းမှုအစီရင်ခံစာ"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"ချွတ်ယွင်းမှတ်တမ်း"</string>
<string name="bugreport_message" msgid="5212529146119624326">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"လက်ငင်းတုံ့ပြန်နိုင်သည့် အစီရင်ခံချက်"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"အခြေအနေတော်တော်များများတွင် ၎င်းကိုအသုံးပြုပါ။ ၎င်းသည် အစီရင်ခံစာကို မှတ်သားခြင်း၊ ပြဿနာအကြောင်း နောက်ထပ်အသေးစိတ်များကို ထည့်သွင်းခြင်းနှင့် မျက်နှာပြင်ပုံဖမ်းယူခြင်းတို့ကို ပြုလုပ်ခွင့်ပေးပါသည်။ ပေးပို့ရန် အလွန်ကြာပြီး အသုံးပြုခြင်းနည်းပါးသည့်အပိုင်းကို ၎င်းက ချန်ခဲ့နိုင်ပါသည်။"</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS စာတိုစနစ်"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ဖိုင်နှင့် မှတ်တမ်းများ"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ဖိုင်နှင့် မှတ်တမ်းများ"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"သင့်စက်ရှိ ဖိုင်နှင့် မှတ်တမ်းများ သုံးခွင့်"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"သီချင်းနှင့် အခြားအသံဖိုင်"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"သင့်စက်ပေါ်ရှိ အသံဖိုင်များကို သုံးနိုင်သည်"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ဓာတ်ပုံနှင့် ဗီဒီယိုများ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"သင့်စက်ပေါ်ရှိ ပုံနှင့် ဗီဒီယိုဖိုင်များကို သုံးနိုင်သည်"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"တေးဂီတနှင့် အသံ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"သင့်စက်တွင် တေးဂီတနှင့် အသံများ ဖွင့်နိုင်သည်"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ဓာတ်ပုံနှင့် ဗီဒီယိုများ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"သင့်စက်တွင် ဓာတ်ပုံနှင့် ဗီဒီယိုများ ဖွင့်နိုင်သည်"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"မိုက်ခရိုဖုန်း"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"အသံဖမ်းခြင်း"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ကိုယ်ခန္ဓာလှုပ်ရှားမှု"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြခြင်း"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"ဖြတ်လမ်းလင့်ခ်များ ထည့်သွင်းခြင်း"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ပြောင်းလဲခွင့် ပေးခြင်း"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ၏ လုပ်ဆောင်ချက်မပါဘဲ ပင်မစာမျက်နှာ ဖြတ်လမ်းလင့်ခ်များကို ထည့်သွင်းခွင့်ပေးသည်။"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"အတိုကောက်များ ဖယ်ထုတ်ခြင်း"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ဖယ်ရှားခွင့် ပေးခြင်း"</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"အထွက် ခေါ်ဆိုမှုများအား လမ်းလွှဲပြောင်းခြင်း"</string>
@@ -594,7 +594,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"အခြားလက်ဗွေဖြင့် စမ်းကြည့်ပါ"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း သင့်လက်ချောင်း၏တည်နေရာကို အနည်းငယ်ပြောင်းပါ"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း သင့်လက်ချောင်း၏ အနေအထားကို အနည်းငယ်ပြောင်းပါ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"လက်ဗွေကို မသိရှိပါ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'မနှောင့်ယှက်ရ\' ပြောင်းလဲသွားပါပြီ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ပိတ်ထားသည့်အရာများကို ကြည့်ရန် တို့ပါ။"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"အကြောင်းကြားချက် ဆက်တင်များ စိစစ်ရန်"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 မှစ၍ ထည့်သွင်းသော အက်ပ်များသည် အကြောင်းကြားချက်များပို့ရန် သင်၏ခွင့်ပြုချက် လိုအပ်ပါမည်။ ရှိပြီးသားအက်ပ်များအတွက် ဤခွင့်ပြုချက်ကိုပြောင်းရန် တို့ပါ။"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"နောက်မှ သတိပေးပါ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ပယ်ရန်"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"စနစ်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 01bb155..16c69dc 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -171,7 +171,7 @@
<string name="httpErrorBadUrl" msgid="754447723314832538">"Kunne ikke åpne siden fordi nettadressen er ugyldig."</string>
<string name="httpErrorFile" msgid="3400658466057744084">"Fikk ikke tilgang til filen."</string>
<string name="httpErrorFileNotFound" msgid="5191433324871147386">"Fant ikke den forespurte filen."</string>
- <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"For mange forespørsler blir behandlet. Prøv igjen senere."</string>
+ <string name="httpErrorTooManyRequests" msgid="2149677715552037198">"For mange forespørsler blir behandlet. Prøv på nytt senere."</string>
<string name="notification_title" msgid="5783748077084481121">"Påloggingsfeil for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="2341041749565687871">"Synkronisering"</string>
<string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"Kan ikke synkronisere"</string>
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"åpne kalenderen din"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og lese SMS-meldinger"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Filer og dokumenter"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"åpne filer og dokumenter på enheten din"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musikk og annen lyd"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"få tilgang til lydfiler på enheten"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Bilder og videoer"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"få tilgang til bilder og videofiler på enheten"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musikk og lyd"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"bruke musikk og lyd på enheten"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Bilder og videoer"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"bruke bilder og videoer på enheten"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ta opp lyd"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
@@ -609,7 +609,7 @@
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrykk-operasjonen ble avbrutt av brukeren."</string>
<string name="fingerprint_error_lockout" msgid="7853461265604738671">"For mange forsøk. Prøv på nytt senere."</string>
<string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"For mange forsøk. Fingeravtrykkssensoren er slått av."</string>
- <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv igjen."</string>
+ <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv på nytt."</string>
<string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string>
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
@@ -634,7 +634,7 @@
<string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Opplåsing med fingeravtrykk"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Kan ikke bruke fingeravtrykkssensoren"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Gå til en reparasjonsleverandør."</string>
- <string name="face_acquired_insufficient" msgid="2150805835949162453">"Kunne ikke ta opp nøyaktige ansiktsdata Prøv igjen"</string>
+ <string name="face_acquired_insufficient" msgid="2150805835949162453">"Kunne ikke ta opp nøyaktige ansiktsdata Prøv på nytt"</string>
<string name="face_acquired_too_bright" msgid="8070756048978079164">"For lyst. Prøv svakere belysning."</string>
<string name="face_acquired_too_dark" msgid="252573548464426546">"For mørkt. Prøv sterkere belysning."</string>
<string name="face_acquired_too_close" msgid="1628767882971469833">"Flytt telefonen lengre unna"</string>
@@ -647,7 +647,7 @@
<string name="face_acquired_not_detected" msgid="2945945257956443257">"Hold ansiktet ditt rett foran telefonen."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"For mye bevegelse. Hold telefonen stødig."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Registrer ansiktet ditt på nytt."</string>
- <string name="face_acquired_too_different" msgid="4699657338753282542">"Kan ikke gjenkjenne ansiktet lenger. Prøv igjen."</string>
+ <string name="face_acquired_too_different" msgid="4699657338753282542">"Kan ikke gjenkjenne ansiktet lenger. Prøv på nytt."</string>
<string name="face_acquired_too_similar" msgid="7684650785108399370">"For likt – endre posituren din."</string>
<string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Vri hodet ditt litt mindre."</string>
<string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Vri hodet litt mindre."</string>
@@ -661,10 +661,10 @@
<string name="face_error_no_space" msgid="5649264057026021723">"Kan ikke lagre nye ansiktsdata. Slett gamle data først."</string>
<string name="face_error_canceled" msgid="2164434737103802131">"Ansikt-operasjonen ble avbrutt."</string>
<string name="face_error_user_canceled" msgid="5766472033202928373">"Ansiktslås ble avbrutt av brukeren"</string>
- <string name="face_error_lockout" msgid="7864408714994529437">"For mange forsøk. Prøv igjen senere."</string>
+ <string name="face_error_lockout" msgid="7864408714994529437">"For mange forsøk. Prøv på nytt senere."</string>
<string name="face_error_lockout_permanent" msgid="3277134834042995260">"For mange forsøk. Ansiktslås er slått av."</string>
<string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"For mange forsøk. Skriv inn skjermlås i stedet."</string>
- <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan ikke bekrefte ansiktet. Prøv igjen."</string>
+ <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan ikke bekrefte ansiktet. Prøv på nytt."</string>
<string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har ikke konfigurert ansiktslås"</string>
<string name="face_error_hw_not_present" msgid="7940978724978763011">"Ansiktslås støttes ikke på denne enheten"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidig slått av."</string>
@@ -952,7 +952,7 @@
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av nettbrettet. Nettbrettet blir nå tilbakestilt til fabrikkinnstillingene."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"Du har prøvd å låse opp Android TV-enheten din <xliff:g id="NUMBER">%d</xliff:g> ganger. Android TV-enheten din tilbakestilles nå til fabrikkstandard."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av telefonen. Telefonen blir nå tilbakestilt til fabrikkinnstillingene."</string>
- <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Prøv igjen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Har du glemt mønsteret?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Opplåsing av konto"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"For mange forsøk på tegning av mønster"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ikke forstyrr er endret"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Trykk for å sjekke hva som er blokkert."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Gjennomgå varslingsinnstillingene"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Fra og med Android 13 må apper du installerer, få tillatelse til å sende varsler. Trykk for å endre denne tillatelsen for eksisterende apper."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Påminn meg senere"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Lukk"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b12c5c0..629678f 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"तपाईंको पात्रोमाथि पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS सन्देशहरू पठाउनुहोस् र हेर्नुहोस्"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"फाइल र डकुमेन्टहरू"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"फाइल तथा डकुमेन्टहरू"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"आफ्नो डिभाइसमा भएका फाइल र डकुमेन्टहरू प्रयोग गर्नुहोस्"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"सङ्गीत तथा अन्य अडियो"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"तपाईंको डिभाइसमा भएका अडियो फाइलहरू प्रयोग गर्ने"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फोटो तथा भिडियोहरू"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"तपाईंको डिभाइसमा भएका फोटो तथा भिडियो फाइलहरू प्रयोग गर्ने"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"सङ्गीत तथा अडियो"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"तपाईंको डिभाइसबाट सङ्गीत तथा अडियो सुन्ने अनुमति"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"फोटो र भिडियोहरू"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"तपाईंको डिभाइसबाट फोटो तथा भिडियोहरू हेर्ने अनुमति"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"माइक्रोफोन"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"शारीरिक क्रियाकलाप"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट इन्स्टल गर्ने"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिन्छ।"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हाल्ने अनुमति दिन्छ।"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"सर्टकटहरूको स्थापन रद्द गर्नुहोस्"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हटाउनको लागि अनुमति दिन्छ।"</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"बहिर्गमन कलहरूलाई अर्को मार्ग दिनुहोस्"</string>
@@ -395,7 +395,7 @@
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"यो एपले ब्याकग्राउन्डमा डेटा प्रयोग गर्नसक्छ। यसले गर्दा धेरै डेटा प्रयोग हुनसक्छ।"</string>
<string name="permlab_persistentActivity" msgid="464970041740567970">"एपहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
<string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य एपहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य अनुप्रयोगहरूका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android टिभी यन्त्र सुस्त हुन सक्छ।"</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य एपका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android टिभी यन्त्र सुस्त हुन सक्छ।"</string>
<string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string>
<string name="permdesc_foregroundService" msgid="8720071450020922795">"एपलाई अग्रभूमिका सेवाहरू प्रयोग गर्ने अनुमति दिन्छ।"</string>
@@ -460,7 +460,7 @@
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"ब्याकग्राउन्डमा फोटो खिच्नुहोस् तथा भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permdesc_backgroundCamera" msgid="1615291686191138250">"यो एपले जुनसुकै बेला क्यामेराको प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ।"</string>
<string name="permlab_systemCamera" msgid="3642917457796210580">"एप वा सेवालाई फोटो र भिडियो खिच्न प्रणालीका क्यामेराहरूमाथि पहुँच राख्न दिनुहोस्"</string>
- <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
+ <string name="permdesc_systemCamera" msgid="5938360914419175986">"प्रणालीको यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै बेला प्रणालीको क्यामेरा प्रयोग गरी फोटो खिच्न र भिडियो रेकर्ड गर्न सक्छ। एपसँग पनि android.permission.CAMERA प्रयोग गर्ने अनुमति हुनु पर्छ"</string>
<string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"कुनै एप वा सेवालाई खोलिँदै वा बन्द गरिँदै गरेका क्यामेरा यन्त्रहरूका बारेमा कलब्याक प्राप्त गर्ने अनुमति दिनुहोस्।"</string>
<string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"कुनै क्यामेरा यन्त्र खोलिँदा (कुन अनुप्रयोगले खोलेको भन्ने बारेमा) वा बन्द गरिँदा यो एपले कलब्याक प्राप्त गर्न सक्छ।"</string>
<string name="permlab_vibrate" msgid="8596800035791962017">"कम्पन नियन्त्रण गर्नुहोस्"</string>
@@ -507,7 +507,7 @@
<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 टिभी यन्त्रले चिनेका खाताहरूको सूची प्राप्त गर्ने अनुमति दिन्छ। उक्त सूचीमा तपाईंले स्थापना गर्नुभएका एपहरूले बनाएका कुनै पनि खाताहरू पर्न सक्छन्।"</string>
- <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"फोनलाई थाहा भएका खाताहरूको सूची प्राप्त गर्न एपलाई अनुमति दिन्छ। यसले तपाईँले स्थापना गर्नु भएका अनुप्रयोगहरूबाट सृजित कुनै खाताहरू समावेश हुन सक्छ।"</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>
@@ -714,7 +714,7 @@
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"नेटवर्क उपयोग लेखालाई परिमार्जन गर्नुहोस्"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"एपलाई कसरी अनुप्रयोगहरूको विरूद्धमा कसरी नेटवर्क उपयोगी अकाउन्टेड छ भनेर परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"सूचनाहरू पहुँच गर्नुहोस्"</string>
- <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य अनुप्रयोगहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन एपहरूलाई अनुमति दिन्छ।"</string>
+ <string name="permdesc_accessNotifications" msgid="761730149268789668">"अन्य एपहरूबाट पोस्ट गरिएकासहित पुनःप्राप्त गर्न, परीक्षण गर्न र सूचनाहरू हटाउन एपहरूलाई अनुमति दिन्छ।"</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"जानकारी श्रोता सेवामा बाँध्नुहोस्"</string>
<string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"होल्डरलाई सूचना श्रोता सेवाको शीर्ष-स्तरको इन्टरफेस बाँध्न अनुमति दिन्छ। सामान्य एपहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
<string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"सर्त प्रदायक सेवामा जोड्न"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"बाधा नपुर्याउनुहोस् मोड परिवर्तन भएको छ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"रोक लगाइएका कुराहरू जाँच गर्न ट्याप गर्नुहोस्।"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"सूचनाका सेटिङको समीक्षा गर्नुहोस्"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android १३ मा तपाईंले अनुमति दिनुभएका खण्डमा मात्र तपाईंले इन्स्टल गर्नुभएका एपले सूचना पठाउन सक्छन्। यसअघि इन्स्टल गरिसकिएका एपका हकमा यो अनुमति परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"मलाई पछि स्मरण गराइयोस्"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"हटाउनुहोस्"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"प्रणाली"</string>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index f5c82d5..33c9b95 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -26,9 +26,6 @@
<color name="chooser_gradient_background">@color/loading_gradient_background_color_dark</color>
<color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_dark</color>
- <color name="resolver_empty_state_text">#FFFFFF</color>
- <color name="resolver_empty_state_icon">#FFFFFF</color>
-
<color name="call_notification_decline_color">#E66A5E</color>
<color name="call_notification_answer_color">#5DBA80</color>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f544804..5fff691 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"toegang krijgen tot je agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"sms\'jes verzenden en bekijken"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Bestanden en documenten"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Bestanden en documenten"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"bestanden en documenten op je apparaat openen"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziek en andere audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"toegang krijgen tot audiobestanden op je apparaat"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto\'s en video\'s"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"toegang krijgen tot afbeeldingen en videobestanden op je apparaat"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muziek en audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"muziek en audio op je apparaat openen"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foto\'s en video\'s"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"foto\'s en video\'s op je apparaat openen"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfoon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"audio opnemen"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysieke activiteit"</string>
@@ -1224,7 +1224,7 @@
<string name="unsupported_display_size_show" msgid="980129850974919375">"Altijd tonen"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> is gemaakt voor een niet-geschikte versie van het Android-besturingssysteem en kan onverwacht gedrag vertonen. Mogelijk is er een geüpdatete versie van de app beschikbaar."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Altijd tonen"</string>
- <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Controleren op update"</string>
+ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Checken op updates"</string>
<string name="smv_application" msgid="3775183542777792638">"De app <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="smv_process" msgid="1398801497130695446">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> heeft het zelf afgedwongen StrictMode-beleid geschonden."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefoon wordt geüpdatet…"</string>
@@ -1949,7 +1949,7 @@
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je telefoon."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Deze app is ontwikkeld voor een oudere versie van Android en werkt mogelijk niet op de juiste manier. Controleer op updates of neem contact op met de ontwikkelaar."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op update"</string>
+ <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Checken op updates"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open je sms-app om ze te bekijken"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Functionaliteit kan beperkt zijn"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'Niet storen\' is gewijzigd"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tik om te controleren wat er is geblokkeerd."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Instellingen voor meldingen bekijken"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Vanaf Android 13 hebben de apps die je installeert je toestemming nodig om meldingen te sturen. Tik om deze toestemming voor bestaande apps te wijzigen."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Later herinneren"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Sluiten"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Systeem"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index a51d2f3..944fb30 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍ ଆକ୍ସେସ୍ କରେ"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ମେସେଜ୍ ପଠାନ୍ତୁ ଓ ଦେଖନ୍ତୁ"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ଫାଇଲ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକ"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ଫାଇଲ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକ"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଥିବା ଫାଇଲ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ମ୍ୟୁଜିକ ଓ ଅନ୍ୟ ଅଡିଓ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଅଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ଫଟୋ ଓ ଭିଡିଓଗୁଡ଼ିକ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଇମେଜ ଏବଂ ଭିଡିଓ ଫାଇଲଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"ମ୍ୟୁଜିକ ଏବଂ ଅଡିଓ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ଆପଣଙ୍କ ଡିଭାଇସରେ ମ୍ୟୁଜିକ ଏବଂ ଅଡିଓକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ଫଟୋ ଏବଂ ଭିଡିଓଗୁଡ଼ିକ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଫଟୋ ଏବଂ ଭିଡିଓଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ମାଇକ୍ରୋଫୋନ୍"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ଅଡିଓ ରେକର୍ଡ କରେ"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"’ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ’ ବଦଳିଯାଇଛି"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"କ’ଣ ଅବରୋଧ ହୋଇଛି ଯାଞ୍ଚ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ବିଜ୍ଞପ୍ତି ସେଟିଂସକୁ ସମୀକ୍ଷା କରନ୍ତୁ"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13ଠାରୁ, ଆପଣ ଇନଷ୍ଟଲ କରୁଥିବା ଆପ୍ସ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପଠାଇବା ପାଇଁ ଆପଣଙ୍କ ଅନୁମତି ଆବଶ୍ୟକ କରେ। ପୂର୍ବରୁ ଥିବା ଆପ୍ସ ପାଇଁ ଏହି ଅନୁମତିକୁ ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ମୋତେ ପରେ ରିମାଇଣ୍ଡ କର"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ସିଷ୍ଟମ୍"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2bc6da6..e5cc005 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼ਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ਸੰਗੀਤ ਅਤੇ ਹੋਰ ਆਡੀਓ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਚਿੱਤਰਾਂ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"ਸੰਗੀਤ ਅਤੇ ਆਡੀਓ"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਸੰਗੀਤ ਅਤੇ ਆਡੀਓ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">" ਆਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ਸਰੀਰਕ ਸਰਗਰਮੀ"</string>
@@ -350,7 +350,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ਕਿਸੇ ਲਾਕ ਕੀਤੇ ਡੀਵਾਈਸ \'ਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਾਲੀਆਂ ਸਰਗਰਮੀਆਂ ਵਜੋਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ਐਪ ਨੂੰ ਕਿਸੇ ਲਾਕ ਕੀਤੇ ਡੀਵਾਈਸ \'ਤੇ ਪੂਰੀ ਸਕ੍ਰੀਨ ਵਾਲੀਆਂ ਸਰਗਰਮੀਆਂ ਵਜੋਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਉਣ ਦਿੰਦਾ ਹੈ"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ।"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ਸ਼ਾਰਟਕੱਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਹੋਮਸਕ੍ਰੀਨ ਸ਼ਾਰਟਕੱਟ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਰੀਰੂਟ ਕਰੋ"</string>
@@ -1844,7 +1844,7 @@
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ਤੀਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਕਲਪ ਬਦਲ ਗਿਆ ਹੈ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 ਜਾਂ ਇਸ ਤੋਂ ਬਾਅਦ ਵਾਲੇ ਵਰਜਨਾਂ ਵਿੱਚ, ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਐਪਾਂ ਨੂੰ ਸੂਚਨਾਵਾਂ ਭੇਜਣ ਲਈ ਤੁਹਾਡੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਮੌਜੂਦਾ ਐਪਾਂ ਲਈ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਬਦਲਣ ਵਾਸਤੇ ਟੈਪ ਕਰੋ।"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ਬਾਅਦ ਵਿੱਚ ਯਾਦ ਕਰਵਾਓ"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ਖਾਰਜ ਕਰੋ"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ਸਿਸਟਮ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6c96e08..7cada75 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostęp do kalendarza"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"wysyłanie i wyświetlanie SMS‑ów"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Pliki i dokumenty"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Pliki i dokumenty"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"dostęp do plików i dokumentów na urządzeniu"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzyka i inne dźwięki"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"dostęp do plików audio na urządzeniu"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Zdjęcia i filmy"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"dostęp do plików graficznych i wideo na urządzeniu"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzyka i dźwięk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"dostęp do muzyki i dźwięku na urządzeniu"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Zdjęcia i filmy"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"dostęp do zdjęć i filmów na urządzeniu"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"nagrywanie dźwięku"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktywność fizyczna"</string>
@@ -642,7 +642,7 @@
<string name="face_acquired_too_close" msgid="1628767882971469833">"Odsuń telefon."</string>
<string name="face_acquired_too_far" msgid="5098567726427173896">"Przybliż telefon."</string>
<string name="face_acquired_too_high" msgid="4868033653626081839">"Przesuń telefon wyżej."</string>
- <string name="face_acquired_too_low" msgid="1512237819632165945">"Obniż telefon."</string>
+ <string name="face_acquired_too_low" msgid="1512237819632165945">"Przesuń telefon niżej."</string>
<string name="face_acquired_too_right" msgid="2513391513020932655">"Przesuń telefon w lewo."</string>
<string name="face_acquired_too_left" msgid="8882499346502714350">"Przesuń telefon w prawo."</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Patrz prosto na urządzenie."</string>
@@ -1221,7 +1221,7 @@
<string name="launch_warning_original" msgid="3332206576800169626">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została pierwotnie uruchomiona."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"Skala"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"Zawsze pokazuj"</string>
- <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Włącz ponownie, wybierając Ustawienia systemowe > Aplikacje > Pobrane."</string>
+ <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Włącz ponownie, wybierając Ustawienia systemu > Aplikacje > Pobrane."</string>
<string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje obecnie ustawionego rozmiaru wyświetlacza i może działać niestabilnie."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"Zawsze pokazuj"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została skompilowana pod niezgodną wersję systemu Android i może zachowywać się niezgodnie z oczekiwaniami. Sprawdź, czy jest dostępna zaktualizowana wersja aplikacji."</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Zmiany w trybie Nie przeszkadzać"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Kliknij, by sprawdzić, co jest zablokowane."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Sprawdź ustawienia powiadomień"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"W Androidzie 13 i nowszych zainstalowane aplikacje będą potrzebowały zezwolenia na wysyłanie powiadomień. Kliknij, aby zmienić uprawnienia dla istniejących aplikacji."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Przypomnij później"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odrzuć"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index dd51ad9..ef2e8c6 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Arquivos e documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acessar arquivos de imagem e vídeo no seu dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acessar música e áudio no dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acessar fotos e vídeos no dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
@@ -439,8 +439,8 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Este app pode adicionar, remover ou alterar eventos da agenda no seu smartphone. Ele também pode enviar mensagens que aparentem ser de autoria do proprietário da agenda ou alterar eventos sem notificar o proprietário."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar local exato apenas em primeiro plano"</string>
+ <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo \"Não perturbe\" foi alterado"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Revise as configurações de notificação"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"No Android 13 ou em versões mais recentes, os apps que você instala precisam de permissão para enviar notificações. Toque para mudar essa permissão para os apps já instalados."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Lembrar mais tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dispensar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c51cf86..35c9f921 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"aceder ao calendário"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e ver mensagens SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Ficheiros e documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"aceder a ficheiros e documentos no seu dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro áudio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"aceder a ficheiros de áudio no dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"aceder a imagens e ficheiros de áudio no dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"aceder a música e áudio no seu dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"aceder a fotos e vídeos no seu dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo Não incomodar foi alterado"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Analise as definições de notificação"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"A partir do Android 13, as apps que instalar precisam da sua autorização para enviar notificações. Toque para alterar esta autorização para as apps existentes."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Lembrar mais tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ignorar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index dd51ad9..ef2e8c6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Arquivos e documentos"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"acessar arquivos de imagem e vídeo no seu dispositivo"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acessar música e áudio no dispositivo"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acessar fotos e vídeos no dispositivo"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grave áudio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Atividade física"</string>
@@ -439,8 +439,8 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Este app pode adicionar, remover ou alterar eventos da agenda no seu smartphone. Ele também pode enviar mensagens que aparentem ser de autoria do proprietário da agenda ou alterar eventos sem notificar o proprietário."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string>
- <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar local exato apenas em primeiro plano"</string>
+ <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo \"Não perturbe\" foi alterado"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Revise as configurações de notificação"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"No Android 13 ou em versões mais recentes, os apps que você instala precisam de permissão para enviar notificações. Toque para mudar essa permissão para os apps já instalados."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Lembrar mais tarde"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Dispensar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c1e6d87..397cd69 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceseze calendarul"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"trimită și să vadă mesajele SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fișiere și documente"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fișiere și documente"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"să acceseze fișiere și documente de pe dispozitiv"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzică și alt conținut audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"să acceseze fișiere audio de pe dispozitiv"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografii și videoclipuri"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"să acceseze fișiere video și imagini de pe dispozitiv"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzică și conținut audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"să acceseze muzică și conținut audio pe dispozitiv"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotografii și videoclipuri"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"să acceseze fotografii și videoclipuri pe dispozitiv"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"înregistreze sunet"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activitate fizică"</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Funcția Nu deranja s-a schimbat"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Atingeți pentru a verifica ce este blocat."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Examinați setările pentru notificări"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Începând cu Android 13, aplicațiile pe care le instalați necesită permisiunea de a trimite notificări. Atingeți ca să modificați permisiunea pentru aplicațiile existente."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Mai târziu"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Închideți"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ce3cfe7..a691484 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"доступ к календарю"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"отправлять и просматривать SMS-сообщения"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы и документы"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файлы и документы"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"Доступ к файлам и документам на вашем устройстве"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка и другие аудиозаписи"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ к аудиофайлам на вашем устройстве"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото и видео"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"доступ к изображениям и видеофайлам на вашем устройстве"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музыка и аудио"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"доступ к музыке и аудио на вашем устройстве"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Фото и видео"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"доступ к фотографиям и видео на вашем устройстве"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"записывать аудио"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физическая активность"</string>
@@ -352,7 +352,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показ уведомлений в полноэкранном режиме на заблокированном устройстве"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Приложение сможет показывать уведомления в полноэкранном режиме на заблокированном устройстве"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Создание ярлыков"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Приложение сможет добавлять ярлыки на главный экран без вмешательства пользователя."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"приложения смогут добавлять ярлыки на главный экран без вмешательства пользователя."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"Удаление ярлыков"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Приложение сможет удалять ярлыки с главного экрана без вмешательства пользователя."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"Перенаправление исходящих вызовов"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Настройки режима \"Не беспокоить\" изменены"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Нажмите, чтобы проверить настройки."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Проверьте настройки уведомлений"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"В Android 13 и более поздних версий приложения могут отправлять вам уведомления только в том случае, если вы предоставили им такое разрешение. Нажмите, чтобы настроить разрешения для установленных приложений."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Напомнить позже"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Закрыть"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 8fdfeb7..181f317 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"කෙටි පණිවිඩ"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ගොනු සහ ලේඛන"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ගොනු සහ ලේඛන"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"ඔබගේ උපාංගයේ ගොනු සහ ලේඛන වෙත ප්රවේශ වන්න"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"සංගීතය සහ වෙනත් ශ්රව්ය"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ඔබගේ උපාංගයෙහි ඇති ශ්රව්ය ගොනුවලට ප්රවේශ වන්න"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ඡායාරූප සහ වීඩියෝ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"ඔබගේ උපාංගයෙහි ඇති රූප සහ වීඩියෝ ගොනුවලට ප්රවේශ වන්න"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"සංගීතය සහ ශ්රව්ය"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"ඔබගේ උපාංගයේ සංගීතය සහ ශ්රව්ය වෙත ප්රවේශ වන්න"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ඡායාරූප සහ වීඩියෝ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"ඔබගේ උපාංගයේ ඡායාරූප සහ වීඩියෝ වෙත ප්රවේශ වන්න"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"මයික්රොෆෝනය"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ශ්රව්ය පටිගත කරන්න"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ශාරීරික ක්රියාකාරකම"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"බාධා නොකරන්න වෙනස් කර ඇත"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"අවහිර කර ඇති දේ පරීක්ෂා කිරීමට තට්ටු කරන්න."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"දැනුම්දීම් සැකසීම් සමාලෝචනය කරන්න"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 හි සිට ආරම්භ වෙමින්, ඔබ ස්ථාපනය කරන යෙදුම්වලට දැනුම්දීම් යැවීමට ඔබගේ අවසරය අවශ්ය වේ. තිබෙන යෙදුම් සඳහා මෙම අවසරය වෙනස් කිරීමට තට්ටු කරන්න."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"මට පසුව මතක් කරන්න"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ඉවත ලන්න"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"පද්ධතිය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 01583c8..9c0b8b3 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"prístup ku kalendáru"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"posielanie a zobrazovanie SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Súbory a dokumenty"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Súbory a dokumenty"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"prístup k súborom a dokumentom vo vašom zariadení"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Hudba a iné zvuky"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"prístup k zvukovým súborom vo vašom zariadení"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotky a videá"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"prístup k súborom obrázka a videosúborom vo vašom zariadení"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Hudba a zvuk"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"prístup k hudbe a zvuku vo vašom zariadení"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotky a videá"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"prístup k fotkám a videám vo vašom zariadení"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofón"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"nahrávanie zvuku"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fyzická aktivita"</string>
@@ -351,7 +351,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikácii rozbaliť alebo zbaliť stavový riadok."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovanie upozornení ako aktivít na celej obrazovke v uzamknutom zariadení"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Táto možnosť umožňuje aplikácii zobrazovať upozornenia ako aktivity na celej obrazovke v uzamknutom zariadení"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"inštalovať odkazy"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Inštalovať odkazy"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Povoľuje aplikácii pridať odkazy na ploche bez zásahu používateľa."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinštalovať odkazy"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Povoľuje aplikácii odstrániť odkazy na ploche bez zásahu používateľa."</string>
@@ -1846,7 +1846,7 @@
<string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
<string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pred odopnutím požiadať o číslo PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
- <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred uvoľnením požiadať o heslo"</string>
+ <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string>
<string name="package_installed_device_owner" msgid="7035926868974878525">"Nainštaloval správca"</string>
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim bez vyrušení sa zmenil"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Klepnutím skontrolujete, čo je blokované."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Kontrola nastavení upozornení"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"V Androide verzie 13 a novších vyžadujú nainštalované aplikácie povolenie, aby mohli odosielať upozornenia. Klepnutím môžete zmeniť toto povolenie pre existujúce aplikácie."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Pripomenúť neskôr"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavrieť"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f694428..a666c81 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostop do koledarja"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"pošiljanje in ogled sporočil SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Datoteke in dokumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Datoteke in dokumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"dostop do datotek in dokumentov v napravi"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Glasba in drugi zvočni posnetki"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"dostop do zvočnih datotek v napravi"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije in videoposnetki"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"dostop do slik in videodatotek v napravi"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Glasba in zvok"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"dostop do glasbe in zvoka v napravi"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotografije in videoposnetki"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"dostop do fotografij in videoposnetkov v napravi"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"snemanje zvoka"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Telesna dejavnost"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način »ne moti« je spremenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dotaknite se, da preverite, kaj je blokirano."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Preglejte nastavitve obvestil"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"V Androidu 13 in novejših različicah bodo aplikacije, ki jih namestite, za pošiljanje obvestil potrebovale vaše dovoljenje. Dotaknite se, če želite spremeniti to dovoljenje za obstoječe aplikacije."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Opomni me pozneje"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Opusti"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 52fcea3..6810aac0 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"qasje te kalendari yt"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"dërgo dhe shiko mesazhet SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Skedarët dhe dokumentet"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Skedarët dhe dokumentet"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"përfito qasje te skedarët dhe dokumentet në pajisjen tënde"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzikë dhe audio të tjera"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"të ketë qasje te skedarët audio në pajisjen tënde"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografitë dhe videot"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"të ketë qasje te skedarët e imazheve dhe videove në pajisjen tënde"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muzika dhe audioja"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"të qaset te muzika dhe audioja në pajisjen tënde"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotografitë dhe videot"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"të qaset te fotografitë dhe videot në pajisjen tënde"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"regjistro audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Aktiviteti fizik"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Mos shqetëso\" ka ndryshuar"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Trokit për të shënuar atë që është bllokuar"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Rishiko cilësimet e njoftimeve"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Nga Android 13, aplikacionet që instalon kanë nevojë për lejen tënde për të dërguar njoftime. Trokit për ta ndryshuar këtë leje për aplikacionet ekzistuese."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Më kujto më vonë"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Hiq"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistemi"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 0dbef5a..004ea5b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -306,12 +306,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Фајлови и документи"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Фајлови и документи"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"приступање фајловима и документима на уређају"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и други аудио садржај"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"приступ аудио фајловима на уређају"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Слике и видео снимци"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"приступ сликама и видео фајловима на уређају"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика и звук"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"приступ музици и аудио садржају на уређају"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Слике и видео снимци"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"приступ сликама и видео снимцима на уређају"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"снима звук"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Физичке активности"</string>
@@ -351,7 +351,7 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталирање пречица"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Омогућава апликацији да додаје пречице на почетни екран без интервенције корисника."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"да додају пречице на почетни екран без интервенције корисника."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"преусмеравање одлазних позива"</string>
@@ -595,7 +595,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут лагано промените положај прста"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут помало промените положај прста"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отисак прста није препознат"</string>
@@ -2054,8 +2054,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте подешавања обавештења"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Од Android-а 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Подсети ме касније"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Одбаци"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6223b0d..bc4bac5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"skicka och visa sms"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer och dokument"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Filer och dokument"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"visa filer och dokument på enheten"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik och övrigt ljud"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"komma åt ljudfiler på din enhet"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foton och videor"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"komma åt bilder och videofiler på din enhet"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musik och ljud"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"få åtkomst till musik och ljud på enheten"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Foton och videor"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"få åtkomst till foton och videor på enheten"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"spela in ljud"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
@@ -349,7 +349,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Tillåter att appen expanderar eller komprimerar statusfältet."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"visa aviseringar som aktiviteter i helskärm på en låst enhet"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Tillåter att appen visar aviseringar som aktiviteter i helskärm på en låst enhet"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"installera genvägar"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installera genvägar"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Tillåter att en app lägger till genvägar på startskärmen utan åtgärd från användaren."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"avinstallera genvägar"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Tillåter att appen tar bort genvägar på startskärmen utan åtgärd från användaren."</string>
@@ -589,7 +589,7 @@
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengör fingeravtryckssensorn och försök igen"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengör sensorn och försök igen"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tryck på sensorn med ett stadigt tryck"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tryck hårt på sensorn"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du rörde fingret för långsamt. Försök igen."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Testa ett annat fingeravtryck"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Det är för ljust"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Stör ej har ändrats"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tryck om du vill se vad som blockeras."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Granska aviseringsinställningarna"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"I Android 13 behöver appar som du installerar behörighet att skicka aviseringar. Tryck om du vill ändra denna behörighet för befintliga appar."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Påminn mig senare"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Stäng"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index aded067..1511b0a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"ifikie kalenda yako"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"itume na iangalie SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili na hati"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Faili na hati"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"fikia faili na hati kwenye kifaa chako"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziki na sauti nyingine"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fikia faili za sauti kwenye kifaa chako"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Picha na video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"fikia faili za picha na video kwenye kifaa chako"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Muziki na sauti"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"fikia muziki na sauti kwenye kifaa chako"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Picha na video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"fikia picha na video kwenye kifaa chako"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Maikrofoni"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"irekodi sauti"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Mazoezi ya mwili"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Kipengele cha Usinisumbue kimebadilishwa"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Gusa ili uangalie kipengee ambacho kimezuiwa."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Kagua mipangilio ya arifa"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Kuanzia Android toleo la 13, programu unazosakinisha zitahitaji ruhusa yako ili zitume arifa. Gusa ili ubadilishe ruhusa hii kwa programu zilizopo."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Nikumbushe baadaye"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ondoa"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Mfumo"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index b7dd387..522e15d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"கேலெண்டரை அணுகலாம்"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS அனுப்பலாம், வந்த SMSகளைப் பார்க்கலாம்"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ஃபைல்கள் & ஆவணங்கள்"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ஃபைல்களும் ஆவணங்களும்"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"சாதனத்திலுள்ள ஃபைல்களையும் ஆவணங்களையும் அணுகும்"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"இசை & பிற ஆடியோ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"உங்கள் சாதனத்திலுள்ள ஆடியோ ஃபைல்களை அணுகும்"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"படங்கள் & வீடியோக்கள்"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"உங்கள் சாதனத்திலுள்ள படங்களையும் வீடியோ ஃபைல்களையும் அணுகும்"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"இசையும் ஆடியோவும்"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"உங்கள் சாதனத்திலுள்ள இசையையும் ஆடியோவையும் அணுகும்"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"படங்களும் வீடியோக்களும்"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"உங்கள் சாதனத்திலுள்ள படங்களையும் வீடியோக்களையும் அணுகும்"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"மைக்ரோஃபோன்"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ஒலிப் பதிவு செய்யலாம்"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"உடல் செயல்பாடுகள்"</string>
@@ -1712,7 +1712,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="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>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"தொந்தரவு செய்ய வேண்டாம் அமைப்புகள் மாற்றப்பட்டன"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"எவற்றையெல்லாம் தடுக்கிறது என்பதைப் பார்க்க, தட்டவும்."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"அறிவிப்பு அமைப்புகளை மதிப்பாய்வு செய்யுங்கள்"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 பதிப்பு முதல், நீங்கள் நிறுவுகின்ற ஆப்ஸ் உங்களுக்கு அறிவிப்புகளை அனுப்ப அனுமதி தேவை. ஏற்கெனவே உள்ள ஆப்ஸுக்கு இந்த அனுமதியை மாற்ற தட்டவும்."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"பின்னர் நினைவூட்டு"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"நிராகரி"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"சிஸ்டம்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 3b80741..68e57e4 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"మీ క్యాలెండర్ను యాక్సెస్ చేయడానికి"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS మెసేజ్లను పంపడం, వీక్షించడం"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ఫైల్స్ & డాక్యుమెంట్లు"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ఫైల్స్, డాక్యుమెంట్లు"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"మీ పరికరంలోని ఫైల్లు, డాక్యుమెంట్లను యాక్సెస్ చేయండి"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"మ్యూజిక్ & ఇతర ఆడియో"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"మీ పరికరంలోని ఆడియో ఫైల్లను యాక్సెస్ చేయండి"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ఫోటోలు & వీడియోలు"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"మీ పరికరంలోని ఇమేజ్లు, వీడియో ఫైల్లను యాక్సెస్ చేయండి"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"మ్యూజిక్, ఆడియో"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"మీ పరికరంలో మ్యూజిక్, ఆడియోను యాక్సెస్ చేయండి"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"ఫోటోలు, వీడియోలు"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"మీ పరికరంలో ఫోటోలు, వీడియోలను యాక్సెస్ చేయండి"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ఫిజికల్ యాక్టివిటీ"</string>
@@ -1127,7 +1127,7 @@
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"అన్నింటినీ ఎంచుకోండి"</string>
<string name="cut" msgid="2561199725874745819">"కత్తిరించు"</string>
- <string name="copy" msgid="5472512047143665218">"కాపీ చేయి"</string>
+ <string name="copy" msgid="5472512047143665218">"కాపీ చేయండి"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"క్లిప్బోర్డ్కు కాపీ చేయడంలో విఫలమైంది"</string>
<string name="paste" msgid="461843306215520225">"అతికించు"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా అతికించు"</string>
@@ -1224,7 +1224,7 @@
<string name="unsupported_display_size_show" msgid="980129850974919375">"ఎల్లప్పుడూ చూపు"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Android OS యొక్క అననుకూల వెర్షన్ కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> రూపొందించబడింది మరియు ఊహించని సమస్యలు తలెత్తవచ్చు. యాప్ యొక్క అప్డేట్ చేసిన వెర్షన్ అందుబాటులో ఉండవచ్చు."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"ఎల్లప్పుడూ చూపు"</string>
- <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"అప్డేట్ కోసం చెక్ చేయి"</string>
+ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"అప్డేట్ కోసం చెక్ చేయండి"</string>
<string name="smv_application" msgid="3775183542777792638">"<xliff:g id="APPLICATION">%1$s</xliff:g> యాప్ (<xliff:g id="PROCESS">%2$s</xliff:g> ప్రాసెస్) అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
<string name="smv_process" msgid="1398801497130695446">"ప్రక్రియ <xliff:g id="PROCESS">%1$s</xliff:g> అది స్వయంగా అమలు చేసే ఖచ్చితమైన మోడ్ విధానాన్ని ఉల్లంఘించింది."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"ఫోన్ అప్డేట్ అవుతోంది…"</string>
@@ -1949,7 +1949,7 @@
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్డేట్ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్ని సంప్రదించండి."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్డేట్ కోసం తనిఖీ చేయండి"</string>
+ <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్డేట్ కోసం చెక్ చేయండి"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్లు ఉన్నాయి"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"వీక్షించడానికి SMS యాప్ను తెరవండి"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"కొంత ఫంక్షనాలిటీ పరిమితం కావచ్చు"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"నోటిఫికేషన్ సెట్టింగ్లను రివ్యూ చేయండి"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13తో మొదలుకుని, మీరు ఇన్స్టాల్ చేసే యాప్లకు నోటిఫికేషన్లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"తర్వాత గుర్తు చేయి"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"విస్మరించండి"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"సిస్టమ్"</string>
@@ -2140,7 +2139,7 @@
<string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ఈ కంటెంట్ వ్యక్తిగత యాప్తో షేర్ చేయడం సాధ్యం కాదు"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ఈ కంటెంట్ వ్యక్తిగత యాప్తో తెరవడం సాధ్యం కాదు"</string>
<string name="resolver_turn_on_work_apps" msgid="884910835250037247">"వర్క్ ప్రొఫైల్ పాజ్ చేయబడింది"</string>
- <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయి"</string>
+ <string name="resolver_switch_on_work" msgid="463709043650610420">"ఆన్ చేయడానికి ట్యాప్ చేయండి"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్లు లేవు"</string>
<string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్లు లేవు"</string>
<string name="miniresolver_open_in_personal" msgid="3874522693661065566">"<xliff:g id="APP">%s</xliff:g>ను మీ వ్యక్తిగత ప్రొఫైల్లో తెరవాలా?"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 77e1ab1..dcf9fcd 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"เข้าถึงปฏิทิน"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"ส่งและดูข้อความ SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"ไฟล์และเอกสาร"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"ไฟล์และเอกสาร"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"เข้าถึงไฟล์และเอกสารในอุปกรณ์"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"เพลงและเสียงอื่นๆ"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"เข้าถึงไฟล์เสียงในอุปกรณ์"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"รูปภาพและวิดีโอ"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"เข้าถึงไฟล์ภาพและวิดีโอในอุปกรณ์"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"เพลงและเสียง"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"เข้าถึงเพลงและเสียงในอุปกรณ์ได้"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"รูปภาพและวิดีโอ"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"เข้าถึงรูปภาพและวิดีโอในอุปกรณ์ได้"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"ไมโครโฟน"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"บันทึกเสียง"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"การเคลื่อนไหวร่างกาย"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"เปลี่ยน \"ห้ามรบกวน\" แล้ว"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"แตะเพื่อดูรายการที่ถูกบล็อก"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"ตรวจสอบการตั้งค่าการแจ้งเตือน"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"ตั้งแต่ Android 13 เป็นต้นไป แอปที่คุณติดตั้งจะต้องได้รับสิทธิ์จากคุณเพื่อส่งการแจ้งเตือน แตะเพื่อเปลี่ยนแปลงสิทธิ์นี้สำหรับแอปที่มีอยู่"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"เตือนภายหลัง"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ปิด"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ระบบ"</string>
@@ -2104,7 +2103,7 @@
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ไฟล์}other{{file_name} + # ไฟล์}}"</string>
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ไม่พบใครที่แนะนำให้แชร์ด้วย"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"รายชื่อแอป"</string>
- <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่จะบันทึกเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
+ <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"แอปนี้ไม่ได้รับอนุญาตให้บันทึกเสียงแต่อาจเก็บเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"หน้าแรก"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"กลับ"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"แอปล่าสุด"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bb071ad..4179052 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"i-access ang iyong kalendaryo"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"magpadala at tumingin ng mga mensaheng SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Mga file at dokumento"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Mga file at dokumento"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"i-access ang mga file at dokumento sa iyong device"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika at iba pang audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mag-access ng mga audio file sa iyong device"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Mga larawan at video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"mag-access ng mga larawan at video file sa iyong device"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musika at audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"mag-access ng musika at audio sa iyong device"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Mga larawan at video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"mag-access ng mga larawan at video sa iyong device"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikropono"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"mag-record ng audio"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Pisikal na aktibidad"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Binago ang Huwag Istorbohin"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"I-tap para tingnan kung ano ang naka-block."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Suriin ang mga setting ng notification"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Simula sa Android 13, kakailanganin na ng mga app na ii-install mo ang iyong pahintulot para makapagpadala ng mga notification. I-tap para baguhin ang pahintulot na ito para sa mga kasalukuyang app."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ipaalala mamaya"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"I-dismiss"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index add4cc3..046e25c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"takviminize erişme"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS mesajları gönderme ve görüntüleme"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Dosyalar ve dokümanlar"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Dosyalar ve dokümanlar"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızdaki dosyalara ve dokümanlara erişme"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Müzik ve diğer sesler"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdaki ses dosyalarına erişme"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoğraflar ve videolar"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"cihazınızdaki resim ve video dosyalarına erişme"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Müzik ve ses"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"cihazınızdaki müziklere ve seslere erişme"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotoğraflar ve videolar"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"cihazınızdaki fotoğraflara ve videolara erişme"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ses kaydetme"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fiziksel aktivite"</string>
@@ -626,7 +626,7 @@
<string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Yüz Tanıma Kilidi"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Yüz Tanıma Kilidi sorunu"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Yüz modelinizi silmek için dokunup ardından yüzünüzü yeniden ekleyin"</string>
- <string name="face_setup_notification_title" msgid="8843461561970741790">"Yüz Tanıma Kilidi\'ni kurma"</string>
+ <string name="face_setup_notification_title" msgid="8843461561970741790">"Yüz Tanıma Kilidi\'ni kurun"</string>
<string name="face_setup_notification_content" msgid="5463999831057751676">"Telefonunuza bakarak kilidini açın"</string>
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Yüz Tanıma Kilidi\'ni kullanmak için Ayarlar > Gizlilik bölümünden "<b>"Kamera erişimi"</b>"\'ni açın"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kilidi açmak için daha fazla yöntem ayarlayın"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Rahatsız Etmeyin modu değişti"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nelerin engellendiğini kontrol etmek için dokunun."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Bildirim ayarlarını inceleyin"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13\'te başlayarak yüklediğiniz uygulamaların bildirim gönderebilmesi için izniniz gereklidir. Mevcut uygulamalarda bu izni değiştirmek için dokunun."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Sonra hatırlat"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Kapat"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 582dc57..1d045f5 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -307,12 +307,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"отримувати доступ до календаря"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"надсилати та переглядати SMS-повідомлення"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Файли та документи"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Файли й документи"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"отримувати доступ до файлів і документів на вашому пристрої"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика й інше аудіо"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"отримувати доступ до аудіофайлів на вашому пристрої"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото й відео"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"отримувати доступ до відеофайлів на вашому пристрої"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Музика й аудіо"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"отримувати доступ до музики й аудіо на пристрої"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Фото й відео"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"отримувати доступ до фото й відео на пристрої"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Мікрофон"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"записувати аудіо"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Фізична активність"</string>
@@ -351,7 +351,7 @@
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозволяє програмі розгортати чи згортати рядок стану."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Додаток зможе показувати сповіщення як активності на весь екран заблокованого пристрою"</string>
- <string name="permlab_install_shortcut" msgid="7451554307502256221">"створення ярликів"</string>
+ <string name="permlab_install_shortcut" msgid="7451554307502256221">"Створювати ярлики"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Дозволяє програмі самостійно додавати ярлики на головний екран."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"видаляти ярлики"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Дозволяє програмі самостійно вилучати ярлики з головного екрана."</string>
@@ -1479,7 +1479,7 @@
<string name="accessibility_binding_label" msgid="1974602776545801715">"Спеціальні можливості"</string>
<string name="wallpaper_binding_label" msgid="1197440498000786738">"Фоновий мал."</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"Змінити фоновий малюнок"</string>
- <string name="notification_listener_binding_label" msgid="2702165274471499713">"Служба читання сповіщень"</string>
+ <string name="notification_listener_binding_label" msgid="2702165274471499713">"Сервіс читання сповіщень"</string>
<string name="vr_listener_binding_label" msgid="8013112996671206429">"VR-режим"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Постачальник умов"</string>
<string name="notification_ranker_binding_label" msgid="432708245635563763">"Служба встановлення пріоритетності сповіщень"</string>
@@ -2055,8 +2055,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Налаштування режиму \"Не турбувати\" змінено"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Торкніться, щоб перевірити, що заблоковано."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Перегляньте налаштування сповіщень"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Починаючи з ОС Android 13, установленим додаткам потрібно надати дозвіл, щоб вони могли надсилати сповіщення. Натисніть, щоб змінити цей дозвіл для наявних додатків."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Нагадати пізніше"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Закрити"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
@@ -2104,7 +2103,7 @@
<string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"У режимі польоту Bluetooth залишатиметься ввімкненим"</string>
<string name="car_loading_profile" msgid="8219978381196748070">"Завантаження"</string>
<string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} і ще # файл}one{{file_name} і ще # файл}few{{file_name} і ще # файли}many{{file_name} і ще # файлів}other{{file_name} і ще # файлу}}"</string>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Немає рекомендацій щодо людей, з якими можна поділитися"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Немає рекомендацій про те, з ким поділитися"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Список додатків"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Цей додаток не має дозволу на запис, але він може фіксувати звук через цей USB-пристрій."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"На головний екран"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 20c931e5..5ea95e9 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS پیغامات بھیجیں اور دیکھیں"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"فائلز اور دستاویزات"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"فائلز اور دستاویزات"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"آپ کے آلے پر فائلز اور دستاویزات تک رسائی حاصل کریں"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"موسیقی اور دیگر آڈیو"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"آپ کے آلے پر آڈیو فائلز تک رسائی حاصل کریں"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"تصاویر اور ویڈیوز"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"آپ کے آلے پر تصاویر اور ویڈیو فائلز تک رسائی حاصل کریں"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"موسیقی اور آڈیو"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"اپنے آلے پر موسیقی اور آڈیو تک رسائی حاصل کریں"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"تصاویر اور ویڈیوز"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"اپنے آلے پر تصاویر اور ویڈیوز تک رسائی حاصل کریں"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"مائیکروفون"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"آڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"جسمانی سرگرمی"</string>
@@ -1616,7 +1616,7 @@
<string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"اسکرین کو آلہ پر کاسٹ کریں"</string>
<string name="media_route_chooser_searching" msgid="6119673534251329535">"آلات تلاش کر رہا ہے…"</string>
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"ترتیبات"</string>
- <string name="media_route_controller_disconnect" msgid="7362617572732576959">"غیر مربوط کریں"</string>
+ <string name="media_route_controller_disconnect" msgid="7362617572732576959">"منقطع کریں"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"اسکین کر رہا ہے…"</string>
<string name="media_route_status_connecting" msgid="5845597961412010540">"مربوط ہو رہا ہے…"</string>
<string name="media_route_status_available" msgid="1477537663492007608">"دستیاب"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ڈسٹرب نہ کریں\' تبدیل ہو گيا ہے"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"مسدود کی گئی چیزوں کو چیک کرنے کے لیے تھپتھپائیں۔"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"اطلاع کی ترتیبات کا جائزہ لیں"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 کے ساتھ اب آپ جو بھی ایپس انسٹال کریں گے انہیں اطلاعات بھیجنے کے لیے آپ کی اجازت درکار ہوگی۔ موجودہ ایپس کے لیے اس اجازت کو تبدیل کرنے کی خاطر تھپتھپائیں۔"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"بعد میں یاد دلائیں"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"برخاست کریں"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"سسٹم"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 6905f90..22c5cea 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"taqvimingizga kirish"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS xabarlarni yuborish va ko‘rish"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayl va hujjatlar"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Fayl va hujjatlar"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"qurilmangizdagi fayl va hujjatlarga kirish"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqa va boshqa audio"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"qurilmangizdagi audio fayllarga kirish"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Suratlar va videolar"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"qurilmangizdagi rasm va video fayllarga kirish"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Musiqa va audio"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"qurilmadagi musiqa va audioga ruxsat"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Video va suratlar"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"qurilmadagi rasm va videolarga ruxsat"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ovoz yozib olish"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jismoniy harakatlar"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Bezovta qilinmasin rejimi sozlamalari o‘zgartirildi"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nimalar bloklanganini tekshirish uchun bosing"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Bildirishnoma sozlamalarini tekshiring"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 versiyasidan boshlab, oʻrnatiladigan ilovalar bildirishnoma yuborish uchun sizdan ruxsat oladi. Mavjud ilovalarda ushbu ruxsatni oʻzgartirish uchun bosing."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Keyinroq eslatilsin"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Yopish"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Tizim"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4ccbfad..8ea7afa 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"truy cập lịch của bạn"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"Tin nhắn SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"gửi và xem tin nhắn SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Tệp và tài liệu"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Tệp và tài liệu"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"truy cập vào các tệp và tài liệu trên thiết bị của bạn"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Nhạc và âm thanh khác"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"truy cập vào tệp âm thanh trên thiết bị"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Ảnh và video"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"truy cập vào tệp hình ảnh và video trên thiết bị"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Nhạc và âm thanh"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"truy cập vào âm nhạc và âm thanh trên thiết bị của bạn"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Ảnh và video"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"truy cập vào ảnh và video trên thiết bị của bạn"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrô"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ghi âm"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Hoạt động thể chất"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Cài đặt Không làm phiền đã thay đổi"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nhấn để xem những thông báo bị chặn."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Xem lại chế độ cài đặt thông báo"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Bắt đầu trên Android 13, các ứng dụng bạn cài đặt sẽ cần bạn cấp quyền để gửi thông báo. Hãy nhấn để thay đổi quyền này cho các ứng dụng hiện có."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Nhắc tôi sau"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Đóng"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Hệ thống"</string>
@@ -2275,11 +2274,9 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Đã dịch <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Đã dịch thông báo từ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> sang <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Hoạt động trong nền"</string>
- <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
- <skip />
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Một ứng dụng đang tiêu hao pin"</string>
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Một ứng dụng vẫn đang hoạt động"</string>
- <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
- <skip />
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> đang chạy ẩn. Nhấn để quản lý mức sử dụng pin."</string>
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> có thể ảnh hưởng đến thời lượng pin. Hãy nhấn để xem các ứng dụng đang hoạt động."</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" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 33c78c2..16df002 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"访问您的日历"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"短信"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"发送和查看短信"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"文件和文档"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"文件和文档"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"访问您设备上的文件和文档"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音乐和其他音频"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"访问您设备上的音频文件"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"照片和视频"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"访问您设备上的图片和视频文件"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"音乐和音频"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"访问您设备上的音乐和音频"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"照片和视频"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"访问您设备上的照片和视频"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"麦克风"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"录制音频"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"身体活动"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"“勿扰”设置有变更"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"点按即可查看屏蔽内容。"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"查看通知设置"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"从 Android 13 开始,您安装的应用需要您授予相应权限才能发送通知。点按即可为现有应用更改此权限。"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"稍后提醒我"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"关闭"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"系统"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2e891cf..178a129 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"短訊"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送和查看短訊"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案和文件"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"檔案和文件"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案和文件"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"存取裝置上的圖片和影片檔案"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"音樂和音訊"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"在裝置上使用音樂和音訊"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"相片和影片"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"在裝置上使用相片和影片"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"體能活動"</string>
@@ -581,7 +581,7 @@
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
- <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖案或密碼"</string>
+ <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖形或密碼"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string>
@@ -776,7 +776,7 @@
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"設定裝置的全域代理伺服器"</string>
<string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"設定政策啟用時所要使用的裝置全域代理伺服器,只有裝置擁有者可以設定全域代理伺服器。"</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"設定螢幕鎖定密碼期限"</string>
- <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖案的更改頻率。"</string>
+ <string name="policydesc_expirePassword" msgid="9136524319325960675">"變更螢幕鎖定密碼、PIN 或圖形的更改頻率。"</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"設定儲存裝置加密"</string>
<string name="policydesc_encryptedStorage" msgid="1102516950740375617">"必須為儲存的應用程式資料加密。"</string>
<string name="policylab_disableCamera" msgid="5749486347810162018">"停用相機"</string>
@@ -911,7 +911,7 @@
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"螢幕已鎖定。"</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"按選單鍵解鎖或撥打緊急電話。"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"按選單鍵解鎖。"</string>
- <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形以解除鎖定螢幕"</string>
+ <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"畫出解鎖圖形來為螢幕解鎖"</string>
<string name="lockscreen_emergency_call" msgid="7500692654885445299">"緊急電話"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"返回通話"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"正確!"</string>
@@ -940,12 +940,12 @@
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"請參閱使用者指南或與客戶服務中心聯絡。"</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"SIM 卡處於鎖定狀態。"</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"正在解除 SIM 卡鎖定..."</string>
- <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用 Google 登入資料將 Android TV 裝置解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有使用者資料均會遺失。"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,手機將恢復原廠設定,所有使用者資料均會遺失。"</string>
@@ -955,7 +955,7 @@
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"忘記圖形?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"帳戶解鎖"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖案嘗試次數過多"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"圖形嘗試次數過多"</string>
<string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"如要解鎖,請以 Google 帳戶登入。"</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"使用者名稱 (電子郵件)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"密碼"</string>
@@ -966,12 +966,12 @@
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"解除鎖定"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"開啟音效"</string>
<string name="lockscreen_sound_off_label" msgid="2331496559245450053">"關閉音效"</string>
- <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖案"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖案"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"已開始繪畫解鎖圖形"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"已清除解鎖圖形"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"已加入一格"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"已加入 <xliff:g id="CELL_INDEX">%1$s</xliff:g> 點"</string>
- <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖案"</string>
- <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖案區域。"</string>
+ <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"已畫出解鎖圖形"</string>
+ <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"圖形區域。"</string>
<string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
<string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"新增小工具。"</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"空白"</string>
@@ -987,13 +987,13 @@
<string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具已刪除。"</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"展開解鎖區域。"</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"滑動解鎖。"</string>
- <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖案解鎖。"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"圖形解鎖。"</string>
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"面孔解鎖。"</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN 解鎖。"</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM 卡 PIN 碼解鎖。"</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM 卡 PUK 解鎖。"</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"密碼解鎖。"</string>
- <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖案區域。"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"圖形區域。"</string>
<string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"滑動區域。"</string>
<string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string>
@@ -1627,11 +1627,11 @@
<string name="display_manager_overlay_display_name" msgid="5306088205181005861">"重疊效果 #<xliff:g id="ID">%1$d</xliff:g>"</string>
<string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
<string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">"(安全)"</string>
- <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記圖案"</string>
- <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖形不對"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"忘記了圖形"</string>
+ <string name="kg_wrong_pattern" msgid="1342812634464179931">"圖形錯誤"</string>
<string name="kg_wrong_password" msgid="2384677900494439426">"密碼錯誤"</string>
<string name="kg_wrong_pin" msgid="3680925703673166482">"PIN 錯誤"</string>
- <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖案"</string>
+ <string name="kg_pattern_instructions" msgid="8366024510502517748">"畫出圖形"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"輸入 SIM 卡 PIN 碼"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"輸入 PIN 碼"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"輸入密碼"</string>
@@ -1644,7 +1644,7 @@
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK 碼應由 8 位數字組成。"</string>
<string name="kg_invalid_puk" msgid="4809502818518963344">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN 碼不符"</string>
- <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖案嘗試次數過多"</string>
+ <string name="kg_login_too_many_attempts" msgid="699292728290654121">"圖形嘗試次數過多"</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"如要解鎖,請以 Google 帳戶登入。"</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"使用者名稱 (電子郵件)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"密碼"</string>
@@ -1654,16 +1654,16 @@
<string name="kg_login_checking_password" msgid="4676010303243317253">"正在檢查帳戶…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有使用者資料均會失去。"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次無法解鎖 Android TV 裝置。如果再失敗 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次,Android TV 裝置將回復原廠設定,所有使用者資料均會遺失。"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"您嘗試了 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,手機將回復原廠設定,所有使用者資料均會失去。"</string>
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。平板電腦現在將回復原廠設定。"</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"您已 <xliff:g id="NUMBER">%d</xliff:g> 次無法解鎖 Android TV 裝置,Android TV 裝置現在將回復原廠設定。"</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"您嘗試了 <xliff:g id="NUMBER">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。手機現在將回復原廠設定。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您使用電郵帳戶解鎖 Android TV 裝置。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
@@ -1934,20 +1934,20 @@
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法使用「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要權限"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"無法使用相機"</string>
- <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"請繼續在手機上操作"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"請繼續透過手機操作"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"無法使用麥克風"</string>
<string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"無法使用 Android TV 設定"</string>
<string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"無法使用平板電腦設定"</string>
<string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"無法使用手機設定"</string>
- <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用 Android TV 裝置。"</string>
- <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用平板電腦。"</string>
- <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
- <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用 Android TV 裝置。"</string>
- <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用平板電腦。"</string>
- <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"這個應用程式要求進行額外的安全性驗證,請改用 Android TV 裝置。"</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"這個應用程式要求進行額外的安全性驗證,請改用平板電腦。"</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"這個應用程式要求進行額外的安全性驗證,請改用手機。"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用 Android TV 裝置。"</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用平板電腦。"</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機。"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用 Android TV 裝置。"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用平板電腦。"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機。"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"此應用程式要求額外的安全措施,請改用 Android TV 裝置。"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"此應用程式要求額外的安全措施,請改用平板電腦。"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"此應用程式要求額外的安全措施,請改用手機。"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"此應用程式專為舊版 Android 打造,因此可能無法正常運作。請嘗試檢查更新,或與開發人員聯絡。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"您有新的訊息"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"請勿騷擾已變更"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"輕按即可查看封鎖內容。"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"查看通知設定"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"由 Android 13 開始,您安裝的應用程式須獲得授權才能傳送通知。輕按即可變更現有應用程式的這項權限。"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"稍後提醒我"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"關閉"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"系統"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5ec0a0c..f9557da 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取你的日曆"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"簡訊"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送及查看簡訊"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案與文件"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"檔案和文件"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案與文件"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"存取裝置上的圖片和影片檔案"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"音樂和音訊"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"存取裝置上的音樂和音訊"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"相片和影片"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"存取裝置上的相片和影片"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"麥克風"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"錄音"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"體能活動"</string>
@@ -594,7 +594,7 @@
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"請試著調整"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃描時請稍微變更手指的位置"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃描時請稍微改變手指的位置"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"指紋辨識失敗"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"「零打擾」設定已變更"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"輕觸即可查看遭封鎖的項目。"</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"查看通知設定"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"從 Android 13 開始,你安裝的應用程式必須獲得授權,才能傳送通知。輕觸即可為現有應用程式變更這項權限。"</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"稍後提醒我"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"關閉"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"系統"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ee1711c..a2170ae 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -305,12 +305,12 @@
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"finyelela kukhalenda yakho"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"I-SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"thumela uphinde ubuke imilayezo ye-SMS"</string>
- <string name="permgrouplab_storage" msgid="9173334109512154196">"Amafayela namadokhumenti"</string>
+ <string name="permgrouplab_storage" msgid="5570124978732352858">"Amafayela namadokhumenti"</string>
<string name="permgroupdesc_storage" msgid="8352226729501080525">"finyelela amafayela namadokhumenti kudivayisi yakho"</string>
- <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Umculo neminye imisindo"</string>
- <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"finyelela amafayela okulalelwayo edivayisini yakho"</string>
- <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Izithombe namavidiyo"</string>
- <string name="permgroupdesc_readMediaVisual" msgid="173787212014117477">"finyelela amafayela emifanekiso namavidiyo edivayisini yakho"</string>
+ <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Umculo nomsindo"</string>
+ <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"finyelela umculo nomsindo kudivayisi yakho"</string>
+ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Izithombe namavidiyo"</string>
+ <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"finyelela izithombe namavidiyo kudivayisi yakho"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"I-Microphone"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"rekhoda ividiyo"</string>
<string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Umsebenzi womzimba"</string>
@@ -623,7 +623,7 @@
</string-array>
<string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Kunento engahambanga kahle. Zama futhi."</string>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Isithonjana sezigxivizo zeminwe"</string>
- <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ukuvula ubuso"</string>
+ <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ukuvula ngobuso"</string>
<string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Inkinga Ngokuvula ngobuso"</string>
<string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Thepha ukuze usule imodeli yakho yobuso, bese wengeza futhi ubuso"</string>
<string name="face_setup_notification_title" msgid="8843461561970741790">"Setha Ukuvula ngobuso"</string>
@@ -2053,8 +2053,7 @@
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ukungaphazamisi kushintshile"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Thepha ukuze uhlole ukuthi yini evinjelwe."</string>
<string name="review_notification_settings_title" msgid="5102557424459810820">"Buyekeza amasethingi wesaziso"</string>
- <!-- no translation found for review_notification_settings_text (5916244866751849279) -->
- <skip />
+ <string name="review_notification_settings_text" msgid="5916244866751849279">"Kusukela ku-Android 13, ama-app owafakayo adinga imvume yakho yokuthumela izaziso. Thepha ukuze ushintshe le mvume yama-app akhona kakade."</string>
<string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ngikhumbuze ngesinye isikhathi"</string>
<string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Chitha"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Isistimu"</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 71c98d0..5df3dde 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -235,8 +235,6 @@
<!-- Resolver/Chooser -->
<color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
- <color name="resolver_empty_state_text">#FF202124</color>
- <color name="resolver_empty_state_icon">#FF5F6368</color>
<!-- Color for personal app suspension notification button text and icon tint. -->
<color name="personal_apps_suspension_notification_color">#1A73E8</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index edaf8cf..689ff66 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5451,6 +5451,8 @@
<bool name="config_supportsHardwareCamToggle">false</bool>
<!-- Whether a camera intent is launched when the lens cover is toggled -->
<bool name="config_launchCameraOnCameraLensCoverToggle">true</bool>
+ <!-- Whether changing sensor privacy SW setting requires device to be unlocked -->
+ <bool name="config_sensorPrivacyRequiresAuthentication">true</bool>
<!-- List containing the allowed install sources for accessibility service. -->
<string-array name="config_accessibility_allowed_install_source" translatable="false"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b882123..443f9a6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4661,6 +4661,7 @@
<java-symbol type="bool" name="config_supportsHardwareMicToggle" />
<java-symbol type="bool" name="config_supportsHardwareCamToggle" />
<java-symbol type="bool" name="config_launchCameraOnCameraLensCoverToggle" />
+ <java-symbol type="bool" name="config_sensorPrivacyRequiresAuthentication" />
<java-symbol type="dimen" name="starting_surface_icon_size" />
<java-symbol type="dimen" name="starting_surface_default_icon_size" />
diff --git a/core/tests/coretests/src/android/view/BlurAggregatorTest.java b/core/tests/coretests/src/android/view/BlurAggregatorTest.java
index b01f275..ded925e 100644
--- a/core/tests/coretests/src/android/view/BlurAggregatorTest.java
+++ b/core/tests/coretests/src/android/view/BlurAggregatorTest.java
@@ -65,7 +65,7 @@
drawable.setBlurRadius(TEST_BLUR_RADIUS);
final boolean hasUpdates = mAggregator.hasUpdates();
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
- mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions, hasUpdates);
+ mAggregator.getBlurRegionsForFrameLocked(TEST_FRAME_NUMBER, blurRegions, hasUpdates);
return drawable;
}
@@ -154,7 +154,7 @@
assertEquals(1, blurRegions.length);
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
- mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions,
+ mAggregator.getBlurRegionsForFrameLocked(TEST_FRAME_NUMBER, blurRegions,
mAggregator.hasUpdates());
assertEquals(1, blurRegions[0].rect.left);
assertEquals(2, blurRegions[0].rect.top);
@@ -169,7 +169,7 @@
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
assertEquals(1, blurRegions.length);
- float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
assertNull(blurRegionsForSf);
}
@@ -182,7 +182,7 @@
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
assertEquals(1, blurRegions.length);
- float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
assertNotNull(blurRegionsForSf);
assertEquals(1, blurRegionsForSf.length);
@@ -197,7 +197,7 @@
assertEquals(1, blurRegions.length);
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
- float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
assertNotNull(blurRegionsForSf);
assertEquals(1, blurRegionsForSf.length);
@@ -216,7 +216,7 @@
assertEquals(1, blurRegions.length);
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
- float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
assertNotNull(blurRegionsForSf);
assertEquals(1, blurRegionsForSf.length);
@@ -237,19 +237,19 @@
assertEquals(2, blurRegions.length);
// Check that an update in one of the drawables triggers a dispatch of all blur regions
- float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
assertNotNull(blurRegionsForSf);
assertEquals(2, blurRegionsForSf.length);
// Check that the Aggregator deleted all position updates for frame TEST_FRAME_NUMBER
- blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
assertNull(blurRegionsForSf);
// Check that a position update triggers a dispatch of all blur regions
drawable2.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
- blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
assertNotNull(blurRegionsForSf);
assertEquals(2, blurRegionsForSf.length);
@@ -292,7 +292,7 @@
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER + 1, 5, 6, 7, 8);
- final float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
+ final float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
assertNotNull(blurRegionsForSf);
assertEquals(1, blurRegionsForSf.length);
@@ -303,7 +303,7 @@
assertEquals(3f, blurRegionsForSf[0][4]);
assertEquals(4f, blurRegionsForSf[0][5]);
- final float[][] blurRegionsForSfForNextFrame = mAggregator.getBlurRegionsToDispatchToSf(
+ final float[][] blurRegionsForSfForNextFrame = mAggregator.getBlurRegionsForFrameLocked(
TEST_FRAME_NUMBER + 1, blurRegions, /* hasUiUpdates= */ false);
assertNotNull(blurRegionsForSfForNextFrame);
assertEquals(1, blurRegionsForSfForNextFrame.length);
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityLoggerFake.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityLoggerFake.java
index 2ecc261..0dca638 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityLoggerFake.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityLoggerFake.java
@@ -44,6 +44,7 @@
// share completed fields
public int targetType;
public int positionPicked;
+ public boolean isPinned;
CallRecord(int atomId, UiEventLogger.UiEventEnum eventId,
String packageName, InstanceId instanceId) {
@@ -68,12 +69,13 @@
}
CallRecord(int atomId, String packageName, InstanceId instanceId, int targetType,
- int positionPicked) {
+ int positionPicked, boolean isPinned) {
this.atomId = atomId;
this.packageName = packageName;
this.instanceId = instanceId;
this.targetType = targetType;
this.positionPicked = positionPicked;
+ this.isPinned = isPinned;
}
}
@@ -112,9 +114,11 @@
}
@Override
- public void logShareTargetSelected(int targetType, String packageName, int positionPicked) {
+ public void logShareTargetSelected(int targetType, String packageName, int positionPicked,
+ boolean isPinned) {
mCalls.add(new CallRecord(FrameworkStatsLog.RANKING_SELECTED, packageName, getInstanceId(),
- SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), positionPicked));
+ SharesheetTargetSelectedEvent.fromTargetType(targetType).getId(), positionPicked,
+ isPinned));
}
@Override
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
index 2262c05..3858792 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java
@@ -35,6 +35,7 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
+@SuppressWarnings("GuardedBy")
public class BatteryStatsHistoryIteratorTest {
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
@@ -124,7 +125,10 @@
// More than 32k strings
final int eventCount = 0x7FFF + 100;
for (int i = 0; i < eventCount; i++) {
- mBatteryStats.noteAlarmStartLocked("a" + i, null, APP_UID, 3_000_000, 2_000_000);
+ // Names repeat in order to verify de-duping of identical history tags.
+ String name = "a" + (i % 10);
+ mBatteryStats.noteAlarmStartLocked(name, null, APP_UID, 3_000_000, 2_000_000);
+ mBatteryStats.noteAlarmFinishLocked(name, null, APP_UID, 3_500_000, 2_500_000);
}
final BatteryStatsHistoryIterator iterator =
@@ -149,10 +153,23 @@
assertThat(item.time).isEqualTo(2_000_000);
for (int i = 0; i < eventCount; i++) {
+ String name = "a" + (i % 10);
assertThat(iterator.next(item)).isTrue();
+ // Skip a blank event inserted at the start of every buffer
+ if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+ assertThat(iterator.next(item)).isTrue();
+ }
assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
| BatteryStats.HistoryItem.EVENT_FLAG_START);
- assertThat(item.eventTag.string).isEqualTo("a" + i);
+ assertThat(item.eventTag.string).isEqualTo(name);
+
+ assertThat(iterator.next(item)).isTrue();
+ if (item.eventCode == BatteryStats.HistoryItem.EVENT_NONE) {
+ assertThat(iterator.next(item)).isTrue();
+ }
+ assertThat(item.eventCode).isEqualTo(BatteryStats.HistoryItem.EVENT_ALARM
+ | BatteryStats.HistoryItem.EVENT_FLAG_FINISH);
+ assertThat(item.eventTag.string).isEqualTo(name);
}
assertThat(iterator.next(item)).isFalse();
diff --git a/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java b/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
index 8540adb..e717ebb 100644
--- a/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
@@ -75,6 +75,73 @@
}
@Test
+ public void updateThenSetState_timestampOutOfOrder() {
+ LongMultiStateCounter counter = new LongMultiStateCounter(2);
+ counter.setState(0, 1000);
+ counter.updateValue(0, 1000);
+ counter.updateValue(100, 3000);
+ counter.setState(0, 2000); // Note out-of-order timestamp
+ counter.updateValue(200, 4000);
+
+ // If we did not explicitly handle this out-of-order update scenario, we would get
+ // this result:
+ // 1. Time in state-0 at this point is (4000-2000) = 2000
+ // 2. Time since last update is (4000-3000) = 1000.
+ // 3. Counter delta: 100
+ // 4. Proportion of count-0
+ // = prevValue + delta * time-in-state / time-since-last-update
+ // = 100 + 100 * 2000 / 1000
+ // = 300
+ // This would be problematic, because the part (300) would exceed the total (200)
+ assertThat(counter.getCount(0)).isEqualTo(200);
+ }
+
+ @Test
+ public void disableThenUpdate_timestampOutOfOrder() {
+ LongMultiStateCounter counter = new LongMultiStateCounter(2);
+ counter.setState(0, 1000);
+ counter.updateValue(0, 1000);
+ counter.setEnabled(false, 2000);
+ counter.updateValue(123, 1001); // Note out-of-order timestamp
+
+ // If we did not explicitly handle this out-of-order update scenario, we would get
+ // this result:
+ // 1. Time in state-0 at this point is (2000-1000) = 1000
+ // 2. Time since last update is (1001-1000) = 1.
+ // 3. Counter delta: 100
+ // 4. Proportion of count-0
+ // = delta * time-in-state / time-since-last-update
+ // = 123 * 1000 / 1
+ // = 123,000
+ // This would be very very wrong, because the part (123,000) would exceed the total (123)
+ assertThat(counter.getCount(0)).isEqualTo(123);
+ }
+
+ @Test
+ public void updateThenEnable_timestampOutOfOrder() {
+ LongMultiStateCounter counter = new LongMultiStateCounter(2);
+ counter.setState(0, 1000);
+ counter.updateValue(0, 1000);
+ counter.setEnabled(false, 3000);
+ counter.updateValue(100, 5000);
+ // At this point the counter is 50, because it was disabled for half of the time
+ counter.setEnabled(true, 4000); // Note out-of-order timestamp
+ counter.updateValue(200, 6000);
+
+ // If we did not explicitly handle this out-of-order update scenario, we would get
+ // this result:
+ // 1. Time in state-0 at this point is (6000-4000) = 2000
+ // 2. Time since last update is (6000-5000) = 1000.
+ // 3. Counter delta: 100
+ // 4. Proportion of count-0
+ // = prevValue + delta * time-in-state / time-since-last-update
+ // = 50 + 100 * 2000 / 1000
+ // = 250
+ // This would not be great, because the part (250) would exceed the total (200)
+ assertThat(counter.getCount(0)).isEqualTo(150);
+ }
+
+ @Test
public void reset() {
LongMultiStateCounter counter = new LongMultiStateCounter(2);
counter.setState(0, 1000);
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 891c82d..60da2e8 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2575,12 +2575,6 @@
"group": "WM_DEBUG_ANIM",
"at": "com\/android\/server\/wm\/WindowContainer.java"
},
- "397105698": {
- "message": "grantEmbeddedWindowFocus remove request for win=%s dropped since no candidate was found",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"397382873": {
"message": "Moving to PAUSED: %s %s",
"level": "VERBOSE",
@@ -3109,6 +3103,12 @@
"group": "WM_DEBUG_LOCKTASK",
"at": "com\/android\/server\/wm\/LockTaskController.java"
},
+ "958338552": {
+ "message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"959486822": {
"message": "setSyncGroup #%d on %s",
"level": "VERBOSE",
diff --git a/data/keyboards/Vendor_0957_Product_0001.kl b/data/keyboards/Vendor_0957_Product_0001.kl
index 13b4096..54f8808 100644
--- a/data/keyboards/Vendor_0957_Product_0001.kl
+++ b/data/keyboards/Vendor_0957_Product_0001.kl
@@ -44,33 +44,37 @@
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
-key usage 0x000c009F NOTIFICATION
-key usage 0x000c008D GUIDE
-key usage 0x000c0089 TV
-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
-key usage 0x000c0077 BUTTON_3 WAKE #YouTube
-key usage 0x000c0078 BUTTON_4 WAKE #Netflix
-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
+key usage 0x000c0061 CAPTIONS
+
+key usage 0x000c01BD INFO
+key usage 0x000c0037 PERIOD
key usage 0x000c0069 PROG_RED
key usage 0x000c006A PROG_GREEN
+key usage 0x000c006C PROG_YELLOW
key usage 0x000c006B PROG_BLUE
-key usage 0x000c006C PROG_YELLOW
\ No newline at end of file
+key usage 0x000c00B4 MEDIA_SKIP_BACKWARD
+key usage 0x000c00CD MEDIA_PLAY_PAUSE
+key usage 0x000c00B2 MEDIA_RECORD
+key usage 0x000c00B3 MEDIA_SKIP_FORWARD
+
+key usage 0x000c022A BOOKMARK
+key usage 0x000c01A2 ALL_APPS
+key usage 0x000c019C PROFILE_SWITCH
+
+key usage 0x000c0096 SETTINGS
+key usage 0x000c009F NOTIFICATION
+
+key usage 0x000c008D GUIDE
+key usage 0x000c0089 TV
+
+key usage 0x000c009C CHANNEL_UP
+key usage 0x000c009D CHANNEL_DOWN
+
+key usage 0x000c0077 BUTTON_3 WAKE #YouTube
+key usage 0x000c0078 BUTTON_4 WAKE #Netflix
+key usage 0x000c0079 BUTTON_6 WAKE
+key usage 0x000c007A BUTTON_7 WAKE
\ No newline at end of file
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 4b723d1..1c41d06 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -43,6 +43,12 @@
private static native boolean nativeIsSameSurfaceControl(long ptr, long surfaceControlPtr);
private static native SurfaceControl.Transaction nativeGatherPendingTransactions(long ptr,
long frameNumber);
+ private static native void nativeSetTransactionHangCallback(long ptr,
+ TransactionHangCallback callback);
+
+ public interface TransactionHangCallback {
+ void onTransactionHang(boolean isGpuHang);
+ }
/** Create a new connection with the surface flinger. */
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
@@ -184,4 +190,8 @@
public SurfaceControl.Transaction gatherPendingTransactions(long frameNumber) {
return nativeGatherPendingTransactions(mNativeObject, frameNumber);
}
+
+ public void setTransactionHangCallback(TransactionHangCallback hangCallback) {
+ nativeSetTransactionHangCallback(mNativeObject, hangCallback);
+ }
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java
new file mode 100644
index 0000000..4855ad0
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPrivateKey.java
@@ -0,0 +1,46 @@
+/*
+ * 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.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.Authorization;
+import android.system.keystore2.KeyDescriptor;
+
+import java.security.PrivateKey;
+import java.security.interfaces.EdECKey;
+import java.security.spec.NamedParameterSpec;
+
+/**
+ * EdEC private key (instance of {@link PrivateKey} and {@link EdECKey}) backed by keystore.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreEdECPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey {
+ public AndroidKeyStoreEdECPrivateKey(
+ @NonNull KeyDescriptor descriptor, long keyId,
+ @NonNull Authorization[] authorizations,
+ @NonNull String algorithm,
+ @NonNull KeyStoreSecurityLevel securityLevel) {
+ super(descriptor, keyId, authorizations, algorithm, securityLevel);
+ }
+
+ @Override
+ public NamedParameterSpec getParams() {
+ return NamedParameterSpec.ED25519;
+ }
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java
new file mode 100644
index 0000000..642e088
--- /dev/null
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreEdECPublicKey.java
@@ -0,0 +1,145 @@
+/*
+ * 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.security.keystore2;
+
+import android.annotation.NonNull;
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyMetadata;
+
+import java.math.BigInteger;
+import java.security.interfaces.EdECPublicKey;
+import java.security.spec.EdECPoint;
+import java.security.spec.NamedParameterSpec;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * {@link EdECPublicKey} backed by keystore.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreEdECPublicKey extends AndroidKeyStorePublicKey
+ implements EdECPublicKey {
+ /**
+ * DER sequence, as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-4 and
+ * https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.
+ * SEQUENCE (2 elem)
+ * SEQUENCE (1 elem)
+ * OBJECT IDENTIFIER 1.3.101.112 curveEd25519 (EdDSA 25519 signature algorithm)
+ * as defined in https://datatracker.ietf.org/doc/html/rfc8410#section-3
+ * BIT STRING (256 bit) as defined in
+ * https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2
+ */
+ private static final byte[] DER_KEY_PREFIX = new byte[] {
+ 0x30,
+ 0x2a,
+ 0x30,
+ 0x05,
+ 0x06,
+ 0x03,
+ 0x2b,
+ 0x65,
+ 0x70,
+ 0x03,
+ 0x21,
+ 0x00,
+ };
+ private static final int ED25519_KEY_SIZE_BYTES = 32;
+
+ private byte[] mEncodedKey;
+ private EdECPoint mPoint;
+
+ public AndroidKeyStoreEdECPublicKey(
+ @NonNull KeyDescriptor descriptor,
+ @NonNull KeyMetadata metadata,
+ @NonNull String algorithm,
+ @NonNull KeyStoreSecurityLevel iSecurityLevel,
+ @NonNull byte[] encodedKey) {
+ super(descriptor, metadata, encodedKey, algorithm, iSecurityLevel);
+ mEncodedKey = encodedKey;
+
+ int preambleLength = matchesPreamble(DER_KEY_PREFIX, encodedKey);
+ if (preambleLength == 0) {
+ throw new IllegalArgumentException("Key size is not correct size");
+ }
+
+ mPoint = pointFromKeyByteArray(
+ Arrays.copyOfRange(encodedKey, preambleLength, encodedKey.length));
+ }
+
+ @Override
+ AndroidKeyStorePrivateKey getPrivateKey() {
+ return new AndroidKeyStoreEdECPrivateKey(
+ getUserKeyDescriptor(),
+ getKeyIdDescriptor().nspace,
+ getAuthorizations(),
+ "EdDSA",
+ getSecurityLevel());
+ }
+
+ @Override
+ public NamedParameterSpec getParams() {
+ return NamedParameterSpec.ED25519;
+ }
+
+ @Override
+ public EdECPoint getPoint() {
+ return mPoint;
+ }
+
+ private static int matchesPreamble(byte[] preamble, byte[] encoded) {
+ if (encoded.length != (preamble.length + ED25519_KEY_SIZE_BYTES)) {
+ return 0;
+ }
+ if (Arrays.compare(preamble, Arrays.copyOf(encoded, preamble.length)) != 0) {
+ return 0;
+ }
+ return preamble.length;
+ }
+
+ private static EdECPoint pointFromKeyByteArray(byte[] coordinates) {
+ Objects.requireNonNull(coordinates);
+
+ // Oddity of the key is the most-significant bit of the last byte.
+ boolean isOdd = (0x80 & coordinates[coordinates.length - 1]) != 0;
+ // Zero out the oddity bit.
+ coordinates[coordinates.length - 1] &= (byte) 0x7f;
+ // Representation of Y is in little-endian, according to rfc8032 section-3.1.
+ reverse(coordinates);
+ // The integer representing Y starts from the first bit in the coordinates array.
+ BigInteger y = new BigInteger(1, coordinates);
+ return new EdECPoint(isOdd, y);
+ }
+
+ private static void reverse(byte[] coordinateArray) {
+ int start = 0;
+ int end = coordinateArray.length - 1;
+ while (start < end) {
+ byte tmp = coordinateArray[start];
+ coordinateArray[start] = coordinateArray[end];
+ coordinateArray[end] = tmp;
+ start++;
+ end--;
+ }
+ }
+
+ @Override
+ public byte[] getEncoded() {
+ return mEncodedKey.clone();
+ }
+}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index d31499e..0355628 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -224,7 +224,6 @@
String jcaKeyAlgorithm = publicKey.getAlgorithm();
- KeyStoreSecurityLevel securityLevel = iSecurityLevel;
if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
return new AndroidKeyStoreECPublicKey(descriptor, metadata,
iSecurityLevel, (ECPublicKey) publicKey);
@@ -232,8 +231,9 @@
return new AndroidKeyStoreRSAPublicKey(descriptor, metadata,
iSecurityLevel, (RSAPublicKey) publicKey);
} else if (ED25519_OID.equalsIgnoreCase(jcaKeyAlgorithm)) {
- //TODO(b/214203951) missing classes in conscrypt
- throw new ProviderException("Curve " + ED25519_OID + " not supported yet");
+ final byte[] publicKeyEncoded = publicKey.getEncoded();
+ return new AndroidKeyStoreEdECPublicKey(descriptor, metadata, ED25519_OID,
+ iSecurityLevel, publicKeyEncoded);
} else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) {
//TODO(b/214203951) missing classes in conscrypt
throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet");
diff --git a/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java
new file mode 100644
index 0000000..5bd5797
--- /dev/null
+++ b/keystore/tests/src/android/security/keystore2/AndroidKeyStoreEdECPublicKeyTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.security.keystore2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import android.security.KeyStoreSecurityLevel;
+import android.system.keystore2.Authorization;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyMetadata;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.math.BigInteger;
+import java.util.Base64;
+
+@RunWith(AndroidJUnit4.class)
+public class AndroidKeyStoreEdECPublicKeyTest {
+ private static KeyDescriptor descriptor() {
+ final KeyDescriptor keyDescriptor = new KeyDescriptor();
+ keyDescriptor.alias = "key";
+ keyDescriptor.blob = null;
+ keyDescriptor.domain = Domain.APP;
+ keyDescriptor.nspace = -1;
+ return keyDescriptor;
+ }
+
+ private static KeyMetadata metadata(byte[] cert, byte[] certChain) {
+ KeyMetadata metadata = new KeyMetadata();
+ metadata.authorizations = new Authorization[0];
+ metadata.certificate = cert;
+ metadata.certificateChain = certChain;
+ metadata.key = descriptor();
+ metadata.modificationTimeMs = 0;
+ metadata.keySecurityLevel = 1;
+ return metadata;
+ }
+
+ @Mock
+ private KeyStoreSecurityLevel mKeystoreSecurityLevel;
+
+ private static class EdECTestVector {
+ public final byte[] encodedKeyBytes;
+ public final boolean isOdd;
+ public final BigInteger yValue;
+
+ EdECTestVector(String b64KeyBytes, boolean isOdd, String yValue) {
+ this.encodedKeyBytes = Base64.getDecoder().decode(b64KeyBytes);
+ this.isOdd = isOdd;
+ this.yValue = new BigInteger(yValue);
+ }
+ }
+
+ private static final EdECTestVector[] ED_EC_TEST_VECTORS = new EdECTestVector[]{
+ new EdECTestVector("MCowBQYDK2VwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo=",
+ false,
+ "19147682157189290216699341180089409126316261024914226007941553249095116672780"
+ ),
+ new EdECTestVector("MCowBQYDK2VwAyEA/0E1IRNzGj85Ot/TPeXqifkqTkdk4voleH0hIq59D9w=",
+ true,
+ "41640152188550647350742178040529506688513911269563908889464821205156322689535"
+ ),
+ new EdECTestVector("MCowBQYDK2VwAyEAunOvGuenetl9GQSXGVo5L3RIr4OOIpFIv/Zre8qTc/8=",
+ true,
+ "57647939198144376128225770417635248407428273266444593100194116168980378907578"
+ ),
+ new EdECTestVector("MCowBQYDK2VwAyEA2hHqaZ5IolswN1Yd58Y4hzhmUMCCqc4PW5A/SFLmTX8=",
+ false,
+ "57581368614046789120409806291852629847774713088410311752049592044694364885466"
+ ),
+ };
+
+ @Test
+ public void testParsingOfValidKeys() {
+ for (EdECTestVector testVector : ED_EC_TEST_VECTORS) {
+ AndroidKeyStoreEdECPublicKey pkey = new AndroidKeyStoreEdECPublicKey(descriptor(),
+ metadata(null, null), "EdDSA", mKeystoreSecurityLevel,
+ testVector.encodedKeyBytes);
+
+ assertEquals(pkey.getPoint().isXOdd(), testVector.isOdd);
+ assertEquals(pkey.getPoint().getY(), testVector.yValue);
+ }
+ }
+
+ @Test
+ public void testFailedParsingOfKeysWithDifferentOid() {
+ final byte[] testVectorWithIncorrectOid = Base64.getDecoder().decode(
+ "MCowBQYDLGVwAyEADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSo=");
+ assertThrows("OID should be unrecognized", IllegalArgumentException.class,
+ () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA",
+ mKeystoreSecurityLevel, testVectorWithIncorrectOid));
+ }
+
+ @Test
+ public void testFailedParsingOfKeysWithWrongSize() {
+ final byte[] testVectorWithIncorrectKeySize = Base64.getDecoder().decode(
+ "MCwwBQYDK2VwAyMADE+wvQqNHxaERPhAZ0rCFlgFbfWLs/YonPXdSTw0VSrOzg==");
+ assertThrows("Key length should be invalid", IllegalArgumentException.class,
+ () -> new AndroidKeyStoreEdECPublicKey(descriptor(), metadata(null, null), "EdDSA",
+ mKeystoreSecurityLevel, testVectorWithIncorrectKeySize));
+ }
+}
+
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 82f8a13..faada1a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -777,22 +777,14 @@
return null;
}
- private void updateCallbackIfNecessary() {
- updateCallbackIfNecessary(true /* deferCallbackUntilAllActivitiesCreated */);
- }
-
/**
* Notifies listeners about changes to split states if necessary.
- *
- * @param deferCallbackUntilAllActivitiesCreated boolean to indicate whether the split info
- * callback should be deferred until all the
- * organized activities have been created.
*/
- private void updateCallbackIfNecessary(boolean deferCallbackUntilAllActivitiesCreated) {
+ private void updateCallbackIfNecessary() {
if (mEmbeddingCallback == null) {
return;
}
- if (deferCallbackUntilAllActivitiesCreated && !allActivitiesCreated()) {
+ if (!allActivitiesCreated()) {
return;
}
List<SplitInfo> currentSplitStates = getActiveSplitStates();
@@ -848,9 +840,7 @@
for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i).mContainers;
for (TaskFragmentContainer container : containers) {
- if (container.getInfo() == null
- || container.getInfo().getActivities().size()
- != container.collectActivities().size()) {
+ if (!container.taskInfoActivityCountMatchesCreated()) {
return false;
}
}
@@ -1035,11 +1025,8 @@
&& container.getTaskFragmentToken().equals(initialTaskFragmentToken)) {
// The onTaskFragmentInfoChanged callback containing this activity has not
// reached the client yet, so add the activity to the pending appeared
- // activities and send a split info callback to the client before
- // {@link Activity#onCreate} is called.
+ // activities.
container.addPendingAppearedActivity(activity);
- updateCallbackIfNecessary(
- false /* deferCallbackUntilAllActivitiesCreated */);
return;
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 35981d3..26bbcbb 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -145,6 +145,18 @@
return allActivities;
}
+ /**
+ * Checks if the count of activities from the same process in task fragment info corresponds to
+ * the ones created and available on the client side.
+ */
+ boolean taskInfoActivityCountMatchesCreated() {
+ if (mInfo == null) {
+ return false;
+ }
+ return mPendingAppearedActivities.isEmpty()
+ && mInfo.getActivities().size() == collectActivities().size();
+ }
+
ActivityStack toActivityStack() {
return new ActivityStack(collectActivities(), isEmpty());
}
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 6f38eca..39990dc 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -63,7 +63,7 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Cerrar burbuja"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostrar conversación en burbuja"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatea con burbujas"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como iconos flotantes llamadas \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como iconos flotantes llamados \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Controla las burbujas"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toca Gestionar para desactivar las burbujas de esta aplicación"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index b3e22af..0747505 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -63,7 +63,7 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Fermer la bulle"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne pas afficher la conversation dans une bulle"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatter en utilisant des bulles"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou de bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Contrôlez les bulles à tout moment"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Appuyez sur \"Gérer\" pour désactiver les bulles de cette application"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 36b1151..a5fcb97 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -65,9 +65,9 @@
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल्स का इस्तेमाल करके चैट करें"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नई बातचीत फ़्लोटिंग आइकॉन या बबल्स की तरह दिखेंगी. बबल को खोलने के लिए टैप करें. इसे एक जगह से दूसरी जगह ले जाने के लिए खींचें और छोड़ें."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"जब चाहें, बबल्स को कंट्रोल करें"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'प्रबंधित करें\' पर टैप करें"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"इस ऐप्लिकेशन पर बबल्स को बंद करने के लिए \'मैनेज करें\' पर टैप करें"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ठीक है"</string>
- <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के बबल्स मौजूद नहीं हैं"</string>
+ <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के कोई बबल्स नहीं हैं"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 9fd42b2..2f2fea6 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -63,7 +63,7 @@
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Lukk boblen"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ikke vis samtaler i bobler"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat med bobler"</string>
- <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne bobler. Dra for å flytte dem."</string>
+ <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne en boble. Dra for å flytte den."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Kontrollér bobler når som helst"</string>
<string name="bubbles_user_education_manage" msgid="3460756219946517198">"Trykk på Administrer for å slå av bobler for denne appen"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Greit"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index c3fbe55..8fa9f56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -246,9 +246,13 @@
* {@link BackAnimationController}
*/
public void onMotionEvent(MotionEvent event, int action, @BackEvent.SwipeEdge int swipeEdge) {
- if (action == MotionEvent.ACTION_DOWN) {
- initAnimation(event);
- } else if (action == MotionEvent.ACTION_MOVE) {
+ if (action == MotionEvent.ACTION_MOVE) {
+ if (!mBackGestureStarted) {
+ // Let the animation initialized here to make sure the onPointerDownOutsideFocus
+ // could be happened when ACTION_DOWN, it may change the current focus that we
+ // would access it when startBackNavigation.
+ initAnimation(event);
+ }
onMove(event, swipeEdge);
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
ProtoLog.d(WM_SHELL_BACK_PREVIEW,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 227494c..31fc6a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -71,7 +71,7 @@
private long mLastAccessed;
@Nullable
- private Bubbles.SuppressionChangedListener mSuppressionListener;
+ private Bubbles.BubbleMetadataFlagListener mBubbleMetadataFlagListener;
/** Whether the bubble should show a dot for the notification indicating updated content. */
private boolean mShowBubbleUpdateDot = true;
@@ -192,13 +192,13 @@
@VisibleForTesting(visibility = PRIVATE)
public Bubble(@NonNull final BubbleEntry entry,
- @Nullable final Bubbles.SuppressionChangedListener listener,
+ @Nullable final Bubbles.BubbleMetadataFlagListener listener,
final Bubbles.PendingIntentCanceledListener intentCancelListener,
Executor mainExecutor) {
mKey = entry.getKey();
mGroupKey = entry.getGroupKey();
mLocusId = entry.getLocusId();
- mSuppressionListener = listener;
+ mBubbleMetadataFlagListener = listener;
mIntentCancelListener = intent -> {
if (mIntent != null) {
mIntent.unregisterCancelListener(mIntentCancelListener);
@@ -606,8 +606,8 @@
mFlags &= ~Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
}
- if (showInShade() != prevShowInShade && mSuppressionListener != null) {
- mSuppressionListener.onBubbleNotificationSuppressionChange(this);
+ if (showInShade() != prevShowInShade && mBubbleMetadataFlagListener != null) {
+ mBubbleMetadataFlagListener.onBubbleMetadataFlagChanged(this);
}
}
@@ -626,8 +626,8 @@
} else {
mFlags &= ~Notification.BubbleMetadata.FLAG_SUPPRESS_BUBBLE;
}
- if (prevSuppressed != suppressBubble && mSuppressionListener != null) {
- mSuppressionListener.onBubbleNotificationSuppressionChange(this);
+ if (prevSuppressed != suppressBubble && mBubbleMetadataFlagListener != null) {
+ mBubbleMetadataFlagListener.onBubbleMetadataFlagChanged(this);
}
}
@@ -771,12 +771,17 @@
return isEnabled(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE);
}
- void setShouldAutoExpand(boolean shouldAutoExpand) {
+ @VisibleForTesting
+ public void setShouldAutoExpand(boolean shouldAutoExpand) {
+ boolean prevAutoExpand = shouldAutoExpand();
if (shouldAutoExpand) {
enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE);
} else {
disable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE);
}
+ if (prevAutoExpand != shouldAutoExpand && mBubbleMetadataFlagListener != null) {
+ mBubbleMetadataFlagListener.onBubbleMetadataFlagChanged(this);
+ }
}
public void setIsBubble(final boolean isBubble) {
@@ -799,6 +804,10 @@
return (mFlags & option) != 0;
}
+ public int getFlags() {
+ return mFlags;
+ }
+
@Override
public String toString() {
return "Bubble{" + mKey + '}';
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 806c395..f407bdc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -323,7 +323,7 @@
public void initialize() {
mBubbleData.setListener(mBubbleDataListener);
- mBubbleData.setSuppressionChangedListener(this::onBubbleNotificationSuppressionChanged);
+ mBubbleData.setSuppressionChangedListener(this::onBubbleMetadataFlagChanged);
mBubbleData.setPendingIntentCancelledListener(bubble -> {
if (bubble.getBubbleIntent() == null) {
@@ -554,11 +554,10 @@
}
@VisibleForTesting
- public void onBubbleNotificationSuppressionChanged(Bubble bubble) {
+ public void onBubbleMetadataFlagChanged(Bubble bubble) {
// Make sure NoMan knows suppression state so that anyone querying it can tell.
try {
- mBarService.onBubbleNotificationSuppressionChanged(bubble.getKey(),
- !bubble.showInShade(), bubble.isSuppressed());
+ mBarService.onBubbleMetadataFlagChanged(bubble.getKey(), bubble.getFlags());
} catch (RemoteException e) {
// Bad things have happened
}
@@ -1038,7 +1037,15 @@
}
} else {
Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
- inflateAndAdd(bubble, suppressFlyout, showInShade);
+ if (notif.shouldSuppressNotificationList()) {
+ // If we're suppressing notifs for DND, we don't want the bubbles to randomly
+ // expand when DND turns off so flip the flag.
+ if (bubble.shouldAutoExpand()) {
+ bubble.setShouldAutoExpand(false);
+ }
+ } else {
+ inflateAndAdd(bubble, suppressFlyout, showInShade);
+ }
}
}
@@ -1070,7 +1077,8 @@
}
}
- private void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) {
+ @VisibleForTesting
+ public void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) {
// shouldBubbleUp checks canBubble & for bubble metadata
boolean shouldBubble = shouldBubbleUp && canLaunchInTaskView(mContext, entry);
if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
@@ -1096,7 +1104,8 @@
}
}
- private void onRankingUpdated(RankingMap rankingMap,
+ @VisibleForTesting
+ public void onRankingUpdated(RankingMap rankingMap,
HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey) {
if (mTmpRanking == null) {
mTmpRanking = new NotificationListenerService.Ranking();
@@ -1107,19 +1116,22 @@
Pair<BubbleEntry, Boolean> entryData = entryDataByKey.get(key);
BubbleEntry entry = entryData.first;
boolean shouldBubbleUp = entryData.second;
-
if (entry != null && !isCurrentProfile(
entry.getStatusBarNotification().getUser().getIdentifier())) {
return;
}
-
+ if (entry != null && (entry.shouldSuppressNotificationList()
+ || entry.getRanking().isSuspended())) {
+ shouldBubbleUp = false;
+ }
rankingMap.getRanking(key, mTmpRanking);
- boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
- if (isActiveBubble && !mTmpRanking.canBubble()) {
+ boolean isActiveOrInOverflow = mBubbleData.hasAnyBubbleWithKey(key);
+ boolean isActive = mBubbleData.hasBubbleInStackWithKey(key);
+ if (isActiveOrInOverflow && !mTmpRanking.canBubble()) {
// If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason.
// This means that the app or channel's ability to bubble has been revoked.
mBubbleData.dismissBubbleWithKey(key, DISMISS_BLOCKED);
- } else if (isActiveBubble && (!shouldBubbleUp || entry.getRanking().isSuspended())) {
+ } else if (isActiveOrInOverflow && !shouldBubbleUp) {
// If this entry is allowed to bubble, but cannot currently bubble up or is
// suspended, dismiss it. This happens when DND is enabled and configured to hide
// bubbles, or focus mode is enabled and the app is designated as distracting.
@@ -1127,9 +1139,9 @@
// notification, so that the bubble will be re-created if shouldBubbleUp returns
// true.
mBubbleData.dismissBubbleWithKey(key, DISMISS_NO_BUBBLE_UP);
- } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
+ } else if (entry != null && mTmpRanking.isBubble() && !isActive) {
entry.setFlagBubble(true);
- onEntryUpdated(entry, shouldBubbleUp && !entry.getRanking().isSuspended());
+ onEntryUpdated(entry, shouldBubbleUp);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index c98c0e6..e4a0fd0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -159,7 +159,7 @@
private Listener mListener;
@Nullable
- private Bubbles.SuppressionChangedListener mSuppressionListener;
+ private Bubbles.BubbleMetadataFlagListener mBubbleMetadataFlagListener;
private Bubbles.PendingIntentCanceledListener mCancelledListener;
/**
@@ -190,9 +190,8 @@
mMaxOverflowBubbles = mContext.getResources().getInteger(R.integer.bubbles_max_overflow);
}
- public void setSuppressionChangedListener(
- Bubbles.SuppressionChangedListener listener) {
- mSuppressionListener = listener;
+ public void setSuppressionChangedListener(Bubbles.BubbleMetadataFlagListener listener) {
+ mBubbleMetadataFlagListener = listener;
}
public void setPendingIntentCancelledListener(
@@ -311,7 +310,7 @@
bubbleToReturn = mPendingBubbles.get(key);
} else if (entry != null) {
// New bubble
- bubbleToReturn = new Bubble(entry, mSuppressionListener, mCancelledListener,
+ bubbleToReturn = new Bubble(entry, mBubbleMetadataFlagListener, mCancelledListener,
mMainExecutor);
} else {
// Persisted bubble being promoted
@@ -1058,6 +1057,22 @@
return null;
}
+ /**
+ * Get a pending bubble with given notification <code>key</code>
+ *
+ * @param key notification key
+ * @return bubble that matches or null
+ */
+ @VisibleForTesting(visibility = PRIVATE)
+ public Bubble getPendingBubbleWithKey(String key) {
+ for (Bubble b : mPendingBubbles.values()) {
+ if (b.getKey().equals(key)) {
+ return b;
+ }
+ }
+ return null;
+ }
+
@VisibleForTesting(visibility = PRIVATE)
void setTimeSource(TimeSource timeSource) {
mTimeSource = timeSource;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 2b2a2f7..c7db8d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -263,10 +263,10 @@
void onBubbleExpandChanged(boolean isExpanding, String key);
}
- /** Listener to be notified when the flags for notification or bubble suppression changes.*/
- interface SuppressionChangedListener {
- /** Called when the notification suppression state of a bubble changes. */
- void onBubbleNotificationSuppressionChange(Bubble bubble);
+ /** Listener to be notified when the flags on BubbleMetadata have changed. */
+ interface BubbleMetadataFlagListener {
+ /** Called when the flags on BubbleMetadata have changed for the provided bubble. */
+ void onBubbleMetadataFlagChanged(Bubble bubble);
}
/** Listener to be notified when a pending intent has been canceled for a bubble. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index 4b125b1..6305959 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -24,6 +24,7 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Property;
import android.view.GestureDetector;
@@ -37,6 +38,8 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
@@ -80,7 +83,6 @@
private final Rect mTempRect = new Rect();
private FrameLayout mDividerBar;
-
static final Property<DividerView, Integer> DIVIDER_HEIGHT_PROPERTY =
new Property<DividerView, Integer>(Integer.class, "height") {
@Override
@@ -109,6 +111,74 @@
}
};
+ private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ final DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
+ if (isLandscape()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
+ mContext.getString(R.string.accessibility_action_divider_left_full)));
+ if (snapAlgorithm.isFirstSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
+ mContext.getString(R.string.accessibility_action_divider_left_70)));
+ }
+ if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
+ // Only show the middle target if there are more than 1 split target
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
+ mContext.getString(R.string.accessibility_action_divider_left_50)));
+ }
+ if (snapAlgorithm.isLastSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
+ mContext.getString(R.string.accessibility_action_divider_left_30)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
+ mContext.getString(R.string.accessibility_action_divider_right_full)));
+ } else {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
+ mContext.getString(R.string.accessibility_action_divider_top_full)));
+ if (snapAlgorithm.isFirstSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
+ mContext.getString(R.string.accessibility_action_divider_top_70)));
+ }
+ if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
+ // Only show the middle target if there are more than 1 split target
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
+ mContext.getString(R.string.accessibility_action_divider_top_50)));
+ }
+ if (snapAlgorithm.isLastSplitTargetAvailable()) {
+ info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
+ mContext.getString(R.string.accessibility_action_divider_top_30)));
+ }
+ info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
+ mContext.getString(R.string.accessibility_action_divider_bottom_full)));
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityAction(@NonNull View host, int action,
+ @Nullable Bundle args) {
+ DividerSnapAlgorithm.SnapTarget nextTarget = null;
+ DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
+ if (action == R.id.action_move_tl_full) {
+ nextTarget = snapAlgorithm.getDismissEndTarget();
+ } else if (action == R.id.action_move_tl_70) {
+ nextTarget = snapAlgorithm.getLastSplitTarget();
+ } else if (action == R.id.action_move_tl_50) {
+ nextTarget = snapAlgorithm.getMiddleTarget();
+ } else if (action == R.id.action_move_tl_30) {
+ nextTarget = snapAlgorithm.getFirstSplitTarget();
+ } else if (action == R.id.action_move_rb_full) {
+ nextTarget = snapAlgorithm.getDismissStartTarget();
+ }
+ if (nextTarget != null) {
+ mSplitLayout.snapToTarget(mSplitLayout.getDividePosition(), nextTarget);
+ return true;
+ }
+ return super.performAccessibilityAction(host, action, args);
+ }
+ };
+
public DividerView(@NonNull Context context) {
super(context);
}
@@ -179,6 +249,7 @@
mDoubleTapDetector = new GestureDetector(getContext(), new DoubleTapListener());
mInteractive = true;
setOnTouchListener(this);
+ mHandle.setAccessibilityDelegate(mHandleDelegate);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
index 72c8141..dfd4362 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
@@ -29,6 +29,7 @@
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
@@ -63,6 +64,7 @@
Context context,
TvPipBoundsState tvPipBoundsState,
TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
+ PipAppOpsListener pipAppOpsListener,
PipTaskOrganizer pipTaskOrganizer,
TvPipMenuController tvPipMenuController,
PipMediaController pipMediaController,
@@ -79,6 +81,7 @@
context,
tvPipBoundsState,
tvPipBoundsAlgorithm,
+ pipAppOpsListener,
pipTaskOrganizer,
pipTransitionController,
tvPipMenuController,
@@ -140,8 +143,11 @@
@Provides
static TvPipNotificationController provideTvPipNotificationController(Context context,
PipMediaController pipMediaController,
+ PipParamsChangedForwarder pipParamsChangedForwarder,
+ TvPipBoundsState tvPipBoundsState,
@ShellMainThread Handler mainHandler) {
- return new TvPipNotificationController(context, pipMediaController, mainHandler);
+ return new TvPipNotificationController(context, pipMediaController,
+ pipParamsChangedForwarder, tvPipBoundsState, mainHandler);
}
@WMSingleton
@@ -185,4 +191,12 @@
static PipParamsChangedForwarder providePipParamsChangedForwarder() {
return new PipParamsChangedForwarder();
}
+
+ @WMSingleton
+ @Provides
+ static PipAppOpsListener providePipAppOpsListener(Context context,
+ PipTaskOrganizer pipTaskOrganizer,
+ @ShellMainThread ShellExecutor mainExecutor) {
+ return new PipAppOpsListener(context, pipTaskOrganizer::removePip, mainExecutor);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 3335673..db6131a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -78,7 +78,6 @@
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip.PipUiEventLogger;
-import com.android.wm.shell.pip.phone.PipAppOpsListener;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.recents.RecentTasksController;
@@ -435,14 +434,6 @@
return new FloatingContentCoordinator();
}
- @WMSingleton
- @Provides
- static PipAppOpsListener providePipAppOpsListener(Context context,
- PipTouchHandler pipTouchHandler,
- @ShellMainThread ShellExecutor mainExecutor) {
- return new PipAppOpsListener(context, pipTouchHandler.getMotionHelper(), mainExecutor);
- }
-
// Needs handler for registering broadcast receivers
@WMSingleton
@Provides
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 7513e51..1bc9e31 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -51,6 +51,7 @@
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
@@ -63,9 +64,7 @@
import com.android.wm.shell.pip.PipTransitionState;
import com.android.wm.shell.pip.PipUiEventLogger;
import com.android.wm.shell.pip.phone.PhonePipMenuController;
-import com.android.wm.shell.pip.phone.PipAppOpsListener;
import com.android.wm.shell.pip.phone.PipController;
-import com.android.wm.shell.pip.phone.PipKeepClearAlgorithm;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasksController;
@@ -211,8 +210,7 @@
@Provides
static Optional<Pip> providePip(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
- PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
- PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
+ PipBoundsState pipBoundsState, PipMediaController pipMediaController,
PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
WindowManagerShellWrapper windowManagerShellWrapper,
@@ -221,8 +219,8 @@
Optional<OneHandedController> oneHandedController,
@ShellMainThread ShellExecutor mainExecutor) {
return Optional.ofNullable(PipController.create(context, displayController,
- pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
- pipMotionHelper, pipMediaController, phonePipMenuController, pipTaskOrganizer,
+ pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState,
+ pipMediaController, phonePipMenuController, pipTaskOrganizer,
pipTouchHandler, pipTransitionController, windowManagerShellWrapper,
taskStackListener, pipParamsChangedForwarder, oneHandedController, mainExecutor));
}
@@ -241,12 +239,6 @@
@WMSingleton
@Provides
- static PipKeepClearAlgorithm providePipKeepClearAlgorithm() {
- return new PipKeepClearAlgorithm();
- }
-
- @WMSingleton
- @Provides
static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context,
PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) {
return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm);
@@ -333,6 +325,14 @@
@WMSingleton
@Provides
+ static PipAppOpsListener providePipAppOpsListener(Context context,
+ PipTouchHandler pipTouchHandler,
+ @ShellMainThread ShellExecutor mainExecutor) {
+ return new PipAppOpsListener(context, pipTouchHandler.getMotionHelper(), mainExecutor);
+ }
+
+ @WMSingleton
+ @Provides
static PipMotionHelper providePipMotionHelper(Context context,
PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer,
PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java
similarity index 97%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java
index d97d2d6..48a3fc2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAppOpsListener.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.pip.phone;
+package com.android.wm.shell.pip;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
@@ -28,7 +28,6 @@
import android.util.Pair;
import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.pip.PipUtils;
public class PipAppOpsListener {
private static final String TAG = PipAppOpsListener.class.getSimpleName();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
index 8a50f22..65a12d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
@@ -32,6 +32,7 @@
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.Handler;
@@ -64,7 +65,7 @@
*/
public interface ActionListener {
/**
- * Called when the media actions changes.
+ * Called when the media actions changed.
*/
void onMediaActionsChanged(List<RemoteAction> actions);
}
@@ -74,11 +75,21 @@
*/
public interface MetadataListener {
/**
- * Called when the media metadata changes.
+ * Called when the media metadata changed.
*/
void onMediaMetadataChanged(MediaMetadata metadata);
}
+ /**
+ * A listener interface to receive notification on changes to the media session token.
+ */
+ public interface TokenListener {
+ /**
+ * Called when the media session token changed.
+ */
+ void onMediaSessionTokenChanged(MediaSession.Token token);
+ }
+
private final Context mContext;
private final Handler mMainHandler;
private final HandlerExecutor mHandlerExecutor;
@@ -133,6 +144,7 @@
private final ArrayList<ActionListener> mActionListeners = new ArrayList<>();
private final ArrayList<MetadataListener> mMetadataListeners = new ArrayList<>();
+ private final ArrayList<TokenListener> mTokenListeners = new ArrayList<>();
public PipMediaController(Context context, Handler mainHandler) {
mContext = context;
@@ -204,6 +216,31 @@
mMetadataListeners.remove(listener);
}
+ /**
+ * Adds a new token listener.
+ */
+ public void addTokenListener(TokenListener listener) {
+ if (!mTokenListeners.contains(listener)) {
+ mTokenListeners.add(listener);
+ listener.onMediaSessionTokenChanged(getToken());
+ }
+ }
+
+ /**
+ * Removes a token listener.
+ */
+ public void removeTokenListener(TokenListener listener) {
+ listener.onMediaSessionTokenChanged(null);
+ mTokenListeners.remove(listener);
+ }
+
+ private MediaSession.Token getToken() {
+ if (mMediaController == null) {
+ return null;
+ }
+ return mMediaController.getSessionToken();
+ }
+
private MediaMetadata getMediaMetadata() {
return mMediaController != null ? mMediaController.getMetadata() : null;
}
@@ -294,6 +331,7 @@
}
notifyActionsChanged();
notifyMetadataChanged(getMediaMetadata());
+ notifyTokenChanged(getToken());
// TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV)
}
@@ -317,4 +355,10 @@
mMetadataListeners.forEach(l -> l.onMediaMetadataChanged(metadata));
}
}
+
+ private void notifyTokenChanged(MediaSession.Token token) {
+ if (!mTokenListeners.isEmpty()) {
+ mTokenListeners.forEach(l -> l.onMediaSessionTokenChanged(token));
+ }
+ }
}
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 2e8b5b7..42ceb42 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
@@ -76,6 +76,7 @@
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
@@ -109,9 +110,7 @@
private PipAppOpsListener mAppOpsListener;
private PipMediaController mMediaController;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
- private PipKeepClearAlgorithm mPipKeepClearAlgorithm;
private PipBoundsState mPipBoundsState;
- private PipMotionHelper mPipMotionHelper;
private PipTouchHandler mTouchHandler;
private PipTransitionController mPipTransitionController;
private TaskStackListenerImpl mTaskStackListener;
@@ -247,10 +246,6 @@
Set<Rect> unrestricted) {
if (mPipBoundsState.getDisplayId() == displayId) {
mPipBoundsState.setKeepClearAreas(restricted, unrestricted);
- mPipMotionHelper.moveToBounds(mPipKeepClearAlgorithm.adjust(
- mPipBoundsState.getBounds(),
- mPipBoundsState.getRestrictedKeepClearAreas(),
- mPipBoundsState.getUnrestrictedKeepClearAreas()));
}
}
};
@@ -289,8 +284,7 @@
@Nullable
public static Pip create(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
- PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
- PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
+ PipBoundsState pipBoundsState, PipMediaController pipMediaController,
PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
WindowManagerShellWrapper windowManagerShellWrapper,
@@ -305,7 +299,7 @@
}
return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
- pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController,
+ pipBoundsState, pipMediaController,
phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController,
windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
oneHandedController, mainExecutor)
@@ -316,9 +310,7 @@
DisplayController displayController,
PipAppOpsListener pipAppOpsListener,
PipBoundsAlgorithm pipBoundsAlgorithm,
- PipKeepClearAlgorithm pipKeepClearAlgorithm,
@NonNull PipBoundsState pipBoundsState,
- PipMotionHelper pipMotionHelper,
PipMediaController pipMediaController,
PhonePipMenuController phonePipMenuController,
PipTaskOrganizer pipTaskOrganizer,
@@ -341,9 +333,7 @@
mWindowManagerShellWrapper = windowManagerShellWrapper;
mDisplayController = displayController;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
- mPipKeepClearAlgorithm = pipKeepClearAlgorithm;
mPipBoundsState = pipBoundsState;
- mPipMotionHelper = pipMotionHelper;
mPipTaskOrganizer = pipTaskOrganizer;
mMainExecutor = mainExecutor;
mMediaController = pipMediaController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java
deleted file mode 100644
index a83258f..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java
+++ /dev/null
@@ -1,44 +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.wm.shell.pip.phone;
-
-import android.graphics.Rect;
-
-import java.util.Set;
-
-/**
- * Calculates the adjusted position that does not occlude keep clear areas.
- */
-public class PipKeepClearAlgorithm {
-
- /** Returns a new {@code Rect} that does not occlude the provided keep clear areas. */
- public Rect adjust(Rect defaultBounds, Set<Rect> restrictedKeepClearAreas,
- Set<Rect> unrestrictedKeepClearAreas) {
- if (restrictedKeepClearAreas.isEmpty()) {
- return defaultBounds;
- }
- // TODO(b/183746978): implement the adjustment algorithm
- // naively check if areas intersect, an if so move PiP upwards
- Rect outBounds = new Rect(defaultBounds);
- for (Rect r : restrictedKeepClearAreas) {
- if (r.intersect(outBounds)) {
- outBounds.offset(0, r.top - outBounds.bottom);
- }
- }
- return outBounds;
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index e9b6bab..5a21e07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -44,6 +44,7 @@
import com.android.wm.shell.animation.PhysicsAnimator;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 8326588..7667794 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -45,6 +45,7 @@
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
@@ -97,6 +98,7 @@
private final TvPipBoundsState mTvPipBoundsState;
private final TvPipBoundsAlgorithm mTvPipBoundsAlgorithm;
+ private final PipAppOpsListener mAppOpsListener;
private final PipTaskOrganizer mPipTaskOrganizer;
private final PipMediaController mPipMediaController;
private final TvPipNotificationController mPipNotificationController;
@@ -121,6 +123,7 @@
Context context,
TvPipBoundsState tvPipBoundsState,
TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
+ PipAppOpsListener pipAppOpsListener,
PipTaskOrganizer pipTaskOrganizer,
PipTransitionController pipTransitionController,
TvPipMenuController tvPipMenuController,
@@ -136,6 +139,7 @@
context,
tvPipBoundsState,
tvPipBoundsAlgorithm,
+ pipAppOpsListener,
pipTaskOrganizer,
pipTransitionController,
tvPipMenuController,
@@ -153,6 +157,7 @@
Context context,
TvPipBoundsState tvPipBoundsState,
TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
+ PipAppOpsListener pipAppOpsListener,
PipTaskOrganizer pipTaskOrganizer,
PipTransitionController pipTransitionController,
TvPipMenuController tvPipMenuController,
@@ -181,6 +186,7 @@
mTvPipMenuController = tvPipMenuController;
mTvPipMenuController.setDelegate(this);
+ mAppOpsListener = pipAppOpsListener;
mPipTaskOrganizer = pipTaskOrganizer;
pipTransitionController.registerPipTransitionCallback(this);
@@ -287,6 +293,8 @@
}
mTvPipBoundsState.setTvPipManuallyCollapsed(!expanding);
mTvPipBoundsState.setTvPipExpanded(expanding);
+ mPipNotificationController.updateExpansionState();
+
updatePinnedStackBounds();
}
@@ -521,6 +529,12 @@
@Override
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
checkIfPinnedTaskAppeared();
+ mAppOpsListener.onActivityPinned(packageName);
+ }
+
+ @Override
+ public void onActivityUnpinned() {
+ mAppOpsListener.onActivityUnpinned();
}
@Override
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 868e456..320c05c 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
@@ -494,6 +494,14 @@
setFrameHighlighted(false);
}
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ if (!hasWindowFocus) {
+ hideAllUserControls();
+ }
+ }
+
private void animateAlphaTo(float alpha, View view) {
if (view.getAlpha() == alpha) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index 4033f03..61a609d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -16,36 +16,47 @@
package com.android.wm.shell.pip.tv;
+import static android.app.Notification.Action.SEMANTIC_ACTION_DELETE;
+import static android.app.Notification.Action.SEMANTIC_ACTION_NONE;
+
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.RemoteAction;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
-import android.media.MediaMetadata;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.media.session.MediaSession;
+import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ImageUtils;
import com.android.wm.shell.R;
import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.pip.PipParamsChangedForwarder;
+import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import java.util.Objects;
+import java.util.ArrayList;
+import java.util.List;
/**
- * A notification that informs users that PIP is running and also provides PIP controls.
- * <p>Once it's created, it will manage the PIP notification UI by itself except for handling
- * configuration changes.
+ * A notification that informs users that PiP is running and also provides PiP controls.
+ * <p>Once it's created, it will manage the PiP notification UI by itself except for handling
+ * configuration changes and user initiated expanded PiP toggling.
*/
public class TvPipNotificationController {
private static final String TAG = "TvPipNotification";
- private static final boolean DEBUG = TvPipController.DEBUG;
// Referenced in com.android.systemui.util.NotificationChannels.
public static final String NOTIFICATION_CHANNEL = "TVPIP";
@@ -60,6 +71,8 @@
"com.android.wm.shell.pip.tv.notification.action.MOVE_PIP";
private static final String ACTION_TOGGLE_EXPANDED_PIP =
"com.android.wm.shell.pip.tv.notification.action.TOGGLE_EXPANDED_PIP";
+ private static final String ACTION_FULLSCREEN =
+ "com.android.wm.shell.pip.tv.notification.action.FULLSCREEN";
private final Context mContext;
private final PackageManager mPackageManager;
@@ -68,44 +81,88 @@
private final ActionBroadcastReceiver mActionBroadcastReceiver;
private final Handler mMainHandler;
private Delegate mDelegate;
+ private final TvPipBoundsState mTvPipBoundsState;
private String mDefaultTitle;
+ private final List<RemoteAction> mCustomActions = new ArrayList<>();
+ private final List<RemoteAction> mMediaActions = new ArrayList<>();
+ private RemoteAction mCustomCloseAction;
+
+ private MediaSession.Token mMediaSessionToken;
+
/** Package name for the application that owns PiP window. */
private String mPackageName;
- private boolean mNotified;
- private String mMediaTitle;
- private Bitmap mArt;
+
+ private boolean mIsNotificationShown;
+ private String mPipTitle;
+ private String mPipSubtitle;
+
+ private Bitmap mActivityIcon;
public TvPipNotificationController(Context context, PipMediaController pipMediaController,
+ PipParamsChangedForwarder pipParamsChangedForwarder, TvPipBoundsState tvPipBoundsState,
Handler mainHandler) {
mContext = context;
mPackageManager = context.getPackageManager();
mNotificationManager = context.getSystemService(NotificationManager.class);
mMainHandler = mainHandler;
+ mTvPipBoundsState = tvPipBoundsState;
mNotificationBuilder = new Notification.Builder(context, NOTIFICATION_CHANNEL)
.setLocalOnly(true)
- .setOngoing(false)
+ .setOngoing(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setShowWhen(true)
.setSmallIcon(R.drawable.pip_icon)
+ .setAllowSystemGeneratedContextualActions(false)
+ .setContentIntent(createPendingIntent(context, ACTION_FULLSCREEN))
+ .setDeleteIntent(getCloseAction().actionIntent)
.extend(new Notification.TvExtender()
.setContentIntent(createPendingIntent(context, ACTION_SHOW_PIP_MENU))
.setDeleteIntent(createPendingIntent(context, ACTION_CLOSE_PIP)));
mActionBroadcastReceiver = new ActionBroadcastReceiver();
- pipMediaController.addMetadataListener(this::onMediaMetadataChanged);
+ pipMediaController.addActionListener(this::onMediaActionsChanged);
+ pipMediaController.addTokenListener(this::onMediaSessionTokenChanged);
+
+ pipParamsChangedForwarder.addListener(
+ new PipParamsChangedForwarder.PipParamsChangedCallback() {
+ @Override
+ public void onExpandedAspectRatioChanged(float ratio) {
+ updateExpansionState();
+ }
+
+ @Override
+ public void onActionsChanged(List<RemoteAction> actions,
+ RemoteAction closeAction) {
+ mCustomActions.clear();
+ mCustomActions.addAll(actions);
+ mCustomCloseAction = closeAction;
+ updateNotificationContent();
+ }
+
+ @Override
+ public void onTitleChanged(String title) {
+ mPipTitle = title;
+ updateNotificationContent();
+ }
+
+ @Override
+ public void onSubtitleChanged(String subtitle) {
+ mPipSubtitle = subtitle;
+ updateNotificationContent();
+ }
+ });
onConfigurationChanged(context);
}
void setDelegate(Delegate delegate) {
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: setDelegate(), delegate=%s", TAG, delegate);
- }
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: setDelegate(), delegate=%s",
+ TAG, delegate);
+
if (mDelegate != null) {
throw new IllegalStateException(
"The delegate has already been set and should not change.");
@@ -118,90 +175,181 @@
}
void show(String packageName) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: show %s", TAG, packageName);
if (mDelegate == null) {
throw new IllegalStateException("Delegate is not set.");
}
+ mIsNotificationShown = true;
mPackageName = packageName;
- update();
+ mActivityIcon = getActivityIcon();
mActionBroadcastReceiver.register();
+
+ updateNotificationContent();
}
void dismiss() {
- mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
- mNotified = false;
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: dismiss()", TAG);
+
+ mIsNotificationShown = false;
mPackageName = null;
mActionBroadcastReceiver.unregister();
+
+ mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
}
- private void onMediaMetadataChanged(MediaMetadata metadata) {
- if (updateMediaControllerMetadata(metadata) && mNotified) {
- // update notification
- update();
+ private Notification.Action getToggleAction(boolean expanded) {
+ if (expanded) {
+ return createSystemAction(R.drawable.pip_ic_collapse,
+ R.string.pip_collapse, ACTION_TOGGLE_EXPANDED_PIP);
+ } else {
+ return createSystemAction(R.drawable.pip_ic_expand, R.string.pip_expand,
+ ACTION_TOGGLE_EXPANDED_PIP);
}
}
+ private Notification.Action createSystemAction(int iconRes, int titleRes, String action) {
+ Notification.Action.Builder builder = new Notification.Action.Builder(
+ Icon.createWithResource(mContext, iconRes),
+ mContext.getString(titleRes),
+ createPendingIntent(mContext, action));
+ builder.setContextual(true);
+ return builder.build();
+ }
+
+ private void onMediaActionsChanged(List<RemoteAction> actions) {
+ mMediaActions.clear();
+ mMediaActions.addAll(actions);
+ if (mCustomActions.isEmpty()) {
+ updateNotificationContent();
+ }
+ }
+
+ private void onMediaSessionTokenChanged(MediaSession.Token token) {
+ mMediaSessionToken = token;
+ updateNotificationContent();
+ }
+
+ private Notification.Action remoteToNotificationAction(RemoteAction action) {
+ return remoteToNotificationAction(action, SEMANTIC_ACTION_NONE);
+ }
+
+ private Notification.Action remoteToNotificationAction(RemoteAction action,
+ int semanticAction) {
+ Notification.Action.Builder builder = new Notification.Action.Builder(action.getIcon(),
+ action.getTitle(),
+ action.getActionIntent());
+ if (action.getContentDescription() != null) {
+ Bundle extras = new Bundle();
+ extras.putCharSequence(Notification.EXTRA_PICTURE_CONTENT_DESCRIPTION,
+ action.getContentDescription());
+ builder.addExtras(extras);
+ }
+ builder.setSemanticAction(semanticAction);
+ builder.setContextual(true);
+ return builder.build();
+ }
+
+ private Notification.Action[] getNotificationActions() {
+ final List<Notification.Action> actions = new ArrayList<>();
+
+ // 1. Fullscreen
+ actions.add(getFullscreenAction());
+ // 2. Close
+ actions.add(getCloseAction());
+ // 3. App actions
+ final List<RemoteAction> appActions =
+ mCustomActions.isEmpty() ? mMediaActions : mCustomActions;
+ for (RemoteAction appAction : appActions) {
+ if (PipUtils.remoteActionsMatch(mCustomCloseAction, appAction)
+ || !appAction.isEnabled()) {
+ continue;
+ }
+ actions.add(remoteToNotificationAction(appAction));
+ }
+ // 4. Move
+ actions.add(getMoveAction());
+ // 5. Toggle expansion (if expanded PiP enabled)
+ if (mTvPipBoundsState.getDesiredTvExpandedAspectRatio() > 0
+ && mTvPipBoundsState.isTvExpandedPipSupported()) {
+ actions.add(getToggleAction(mTvPipBoundsState.isTvPipExpanded()));
+ }
+ return actions.toArray(new Notification.Action[0]);
+ }
+
+ private Notification.Action getCloseAction() {
+ if (mCustomCloseAction == null) {
+ return createSystemAction(R.drawable.pip_ic_close_white, R.string.pip_close,
+ ACTION_CLOSE_PIP);
+ } else {
+ return remoteToNotificationAction(mCustomCloseAction, SEMANTIC_ACTION_DELETE);
+ }
+ }
+
+ private Notification.Action getFullscreenAction() {
+ return createSystemAction(R.drawable.pip_ic_fullscreen_white,
+ R.string.pip_fullscreen, ACTION_FULLSCREEN);
+ }
+
+ private Notification.Action getMoveAction() {
+ return createSystemAction(R.drawable.pip_ic_move_white, R.string.pip_move,
+ ACTION_MOVE_PIP);
+ }
+
/**
- * Called by {@link PipController} when the configuration is changed.
+ * Called by {@link TvPipController} when the configuration is changed.
*/
void onConfigurationChanged(Context context) {
mDefaultTitle = context.getResources().getString(R.string.pip_notification_unknown_title);
- if (mNotified) {
- // Update the notification.
- update();
- }
+ updateNotificationContent();
}
- private void update() {
- mNotified = true;
+ void updateExpansionState() {
+ updateNotificationContent();
+ }
+
+ private void updateNotificationContent() {
+ if (mPackageManager == null || !mIsNotificationShown) {
+ return;
+ }
+
+ Notification.Action[] actions = getNotificationActions();
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: update(), title: %s, subtitle: %s, mediaSessionToken: %s, #actions: %s", TAG,
+ getNotificationTitle(), mPipSubtitle, mMediaSessionToken, actions.length);
+ for (Notification.Action action : actions) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: action: %s", TAG,
+ action.toString());
+ }
+
mNotificationBuilder
.setWhen(System.currentTimeMillis())
- .setContentTitle(getNotificationTitle());
- if (mArt != null) {
- mNotificationBuilder.setStyle(new Notification.BigPictureStyle()
- .bigPicture(mArt));
- } else {
- mNotificationBuilder.setStyle(null);
- }
+ .setContentTitle(getNotificationTitle())
+ .setContentText(mPipSubtitle)
+ .setSubText(getApplicationLabel(mPackageName))
+ .setActions(actions);
+ setPipIcon();
+
+ Bundle extras = new Bundle();
+ extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, mMediaSessionToken);
+ mNotificationBuilder.setExtras(extras);
+
+ // TvExtender not recognized if not set last.
+ mNotificationBuilder.extend(new Notification.TvExtender()
+ .setContentIntent(createPendingIntent(mContext, ACTION_SHOW_PIP_MENU))
+ .setDeleteIntent(createPendingIntent(mContext, ACTION_CLOSE_PIP)));
mNotificationManager.notify(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP,
mNotificationBuilder.build());
}
- private boolean updateMediaControllerMetadata(MediaMetadata metadata) {
- String title = null;
- Bitmap art = null;
- if (metadata != null) {
- title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE);
- if (TextUtils.isEmpty(title)) {
- title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE);
- }
- art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
- if (art == null) {
- art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
- }
- }
-
- if (TextUtils.equals(title, mMediaTitle) && Objects.equals(art, mArt)) {
- return false;
- }
-
- mMediaTitle = title;
- mArt = art;
-
- return true;
- }
-
-
private String getNotificationTitle() {
- if (!TextUtils.isEmpty(mMediaTitle)) {
- return mMediaTitle;
+ if (!TextUtils.isEmpty(mPipTitle)) {
+ return mPipTitle;
}
-
final String applicationTitle = getApplicationLabel(mPackageName);
if (!TextUtils.isEmpty(applicationTitle)) {
return applicationTitle;
}
-
return mDefaultTitle;
}
@@ -214,10 +362,37 @@
}
}
+ private void setPipIcon() {
+ if (mActivityIcon != null) {
+ mNotificationBuilder.setLargeIcon(mActivityIcon);
+ return;
+ }
+ // Fallback: Picture-in-Picture icon
+ mNotificationBuilder.setLargeIcon(Icon.createWithResource(mContext, R.drawable.pip_icon));
+ }
+
+ private Bitmap getActivityIcon() {
+ if (mContext == null) return null;
+ ComponentName componentName = PipUtils.getTopPipActivity(mContext).first;
+ if (componentName == null) return null;
+
+ Drawable drawable;
+ try {
+ drawable = mPackageManager.getActivityIcon(componentName);
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ int width = mContext.getResources().getDimensionPixelSize(
+ android.R.dimen.notification_large_icon_width);
+ int height = mContext.getResources().getDimensionPixelSize(
+ android.R.dimen.notification_large_icon_height);
+ return ImageUtils.buildScaledBitmap(drawable, width, height, /* allowUpscaling */ true);
+ }
+
private static PendingIntent createPendingIntent(Context context, String action) {
return PendingIntent.getBroadcast(context, 0,
new Intent(action).setPackage(context.getPackageName()),
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
private class ActionBroadcastReceiver extends BroadcastReceiver {
@@ -228,6 +403,7 @@
mIntentFilter.addAction(ACTION_SHOW_PIP_MENU);
mIntentFilter.addAction(ACTION_MOVE_PIP);
mIntentFilter.addAction(ACTION_TOGGLE_EXPANDED_PIP);
+ mIntentFilter.addAction(ACTION_FULLSCREEN);
}
boolean mRegistered = false;
@@ -249,10 +425,8 @@
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
- if (DEBUG) {
- ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
- "%s: on(Broadcast)Receive(), action=%s", TAG, action);
- }
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: on(Broadcast)Receive(), action=%s", TAG, action);
if (ACTION_SHOW_PIP_MENU.equals(action)) {
mDelegate.showPictureInPictureMenu();
@@ -262,14 +436,21 @@
mDelegate.enterPipMovementMenu();
} else if (ACTION_TOGGLE_EXPANDED_PIP.equals(action)) {
mDelegate.togglePipExpansion();
+ } else if (ACTION_FULLSCREEN.equals(action)) {
+ mDelegate.movePipToFullscreen();
}
}
}
interface Delegate {
void showPictureInPictureMenu();
+
void closePip();
+
void enterPipMovementMenu();
+
void togglePipExpansion();
+
+ void movePipToFullscreen();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index 64017e1..d04c349 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -40,6 +40,8 @@
Consts.TAG_WM_SHELL),
WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG,
false, Consts.TAG_WM_SHELL),
+ WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM_SHELL),
TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");
private final boolean mEnabled;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
index 9adf196..51921e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
@@ -98,11 +98,14 @@
/**
* Blocking call that notifies and gets additional split-screen targets when entering
* recents (for example: the dividerBar).
- * @param cancel is true if leaving recents back to split (eg. the gesture was cancelled).
* @param appTargets apps that will be re-parented to display area
*/
- RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
- in RemoteAnimationTarget[] appTargets) = 13;
+ RemoteAnimationTarget[] onGoingToRecentsLegacy(in RemoteAnimationTarget[] appTargets) = 13;
-
+ /**
+ * Blocking call that notifies and gets additional split-screen targets when entering
+ * recents (for example: the dividerBar). Different than the method above in that this one
+ * does not expect split to currently be running.
+ */
+ RemoteAnimationTarget[] onStartingSplitLegacy(in RemoteAnimationTarget[] appTargets) = 14;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index dd2634c..ac76d17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -413,9 +413,22 @@
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
}
- RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel, RemoteAnimationTarget[] apps) {
- if (ENABLE_SHELL_TRANSITIONS || !isSplitScreenVisible()) return null;
+ RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
+ return reparentSplitTasksForAnimation(apps, true /*splitExpectedToBeVisible*/);
+ }
+
+ RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
+ return reparentSplitTasksForAnimation(apps, false /*splitExpectedToBeVisible*/);
+ }
+
+ private RemoteAnimationTarget[] reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
+ boolean splitExpectedToBeVisible) {
+ if (ENABLE_SHELL_TRANSITIONS) return null;
// TODO(b/206487881): Integrate this with shell transition.
+ if (splitExpectedToBeVisible && !isSplitScreenVisible()) return null;
+ // Split not visible, but not enough apps to have split, also return null
+ if (!splitExpectedToBeVisible && apps.length < 2) return null;
+
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
if (mSplitTasksContainerLayer != null) {
// Remove the previous layer before recreating
@@ -442,7 +455,6 @@
transaction.close();
return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
}
-
/**
* Sets drag info to be logged when splitscreen is entered.
*/
@@ -707,11 +719,19 @@
}
@Override
- public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
- RemoteAnimationTarget[] apps) {
+ public RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
final RemoteAnimationTarget[][] out = new RemoteAnimationTarget[][]{null};
executeRemoteCallWithTaskPermission(mController, "onGoingToRecentsLegacy",
- (controller) -> out[0] = controller.onGoingToRecentsLegacy(cancel, apps),
+ (controller) -> out[0] = controller.onGoingToRecentsLegacy(apps),
+ true /* blocking */);
+ return out[0];
+ }
+
+ @Override
+ public RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
+ final RemoteAnimationTarget[][] out = new RemoteAnimationTarget[][]{null};
+ executeRemoteCallWithTaskPermission(mController, "onStartingSplitLegacy",
+ (controller) -> out[0] = controller.onStartingSplitLegacy(apps),
true /* blocking */);
return out[0];
}
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 91f9d25..d543aa7 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
@@ -54,6 +54,9 @@
import static com.android.wm.shell.transition.Transitions.isClosingType;
import static com.android.wm.shell.transition.Transitions.isOpeningType;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -68,6 +71,7 @@
import android.graphics.Rect;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
+import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -147,7 +151,9 @@
private final int mDisplayId;
private SplitLayout mSplitLayout;
+ private ValueAnimator mDividerFadeInAnimator;
private boolean mDividerVisible;
+ private boolean mKeyguardShowing;
private final SyncTransactionQueue mSyncQueue;
private final ShellTaskOrganizer mTaskOrganizer;
private final Context mContext;
@@ -404,6 +410,7 @@
mSplitLayout.init();
// Set false to avoid record new bounds with old task still on top;
mShouldUpdateRecents = false;
+ mIsDividerRemoteAnimating = true;
final WindowContainerTransaction wct = new WindowContainerTransaction();
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct);
@@ -417,7 +424,6 @@
RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps,
final IRemoteAnimationFinishedCallback finishedCallback) {
- mIsDividerRemoteAnimating = true;
RemoteAnimationTarget[] augmentedNonApps =
new RemoteAnimationTarget[nonApps.length + 1];
for (int i = 0; i < nonApps.length; ++i) {
@@ -494,8 +500,10 @@
}
// Using legacy transitions, so we can't use blast sync since it conflicts.
mTaskOrganizer.applyTransaction(wct);
- mSyncQueue.runInSync(t ->
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+ mSyncQueue.runInSync(t -> {
+ setDividerVisibility(true, t);
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
+ });
}
private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
@@ -510,10 +518,6 @@
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
} else {
mSyncQueue.queue(evictWct);
- mSyncQueue.runInSync(t -> {
- setDividerVisibility(true, t);
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
- });
}
}
@@ -623,16 +627,12 @@
}
void onKeyguardVisibilityChanged(boolean showing) {
+ mKeyguardShowing = showing;
if (!mMainStage.isActive()) {
return;
}
- if (ENABLE_SHELL_TRANSITIONS) {
- // Update divider visibility so it won't float on top of keyguard.
- setDividerVisibility(!showing, null /* transaction */);
- }
-
- if (!showing && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
+ if (!mKeyguardShowing && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
if (ENABLE_SHELL_TRANSITIONS) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
@@ -643,7 +643,10 @@
mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
EXIT_REASON_DEVICE_FOLDED);
}
+ return;
}
+
+ setDividerVisibility(!mKeyguardShowing, null);
}
void onFinishedWakingUp() {
@@ -727,6 +730,7 @@
setResizingSplits(false /* resizing */);
t.setWindowCrop(mMainStage.mRootLeash, null)
.setWindowCrop(mSideStage.mRootLeash, null);
+ setDividerVisibility(false, t);
});
// Hide divider and reset its position.
@@ -1055,8 +1059,31 @@
}
private void setDividerVisibility(boolean visible, @Nullable SurfaceControl.Transaction t) {
+ if (visible == mDividerVisible) {
+ return;
+ }
+
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "%s: Request to %s divider bar from %s.", TAG,
+ (visible ? "show" : "hide"), Debug.getCaller());
+
+ // Defer showing divider bar after keyguard dismissed, so it won't interfere with keyguard
+ // dismissing animation.
+ if (visible && mKeyguardShowing) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "%s: Defer showing divider bar due to keyguard showing.", TAG);
+ return;
+ }
+
mDividerVisible = visible;
sendSplitVisibilityChanged();
+
+ if (mIsDividerRemoteAnimating) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "%s: Skip animating divider bar due to it's remote animating.", TAG);
+ return;
+ }
+
if (t != null) {
applyDividerVisibility(t);
} else {
@@ -1066,15 +1093,56 @@
private void applyDividerVisibility(SurfaceControl.Transaction t) {
final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
- if (mIsDividerRemoteAnimating || dividerLeash == null) return;
+ if (dividerLeash == null) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "%s: Skip animating divider bar due to divider leash not ready.", TAG);
+ return;
+ }
+ if (mIsDividerRemoteAnimating) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "%s: Skip animating divider bar due to it's remote animating.", TAG);
+ return;
+ }
+
+ if (mDividerFadeInAnimator != null && mDividerFadeInAnimator.isRunning()) {
+ mDividerFadeInAnimator.cancel();
+ }
if (mDividerVisible) {
- t.show(dividerLeash);
- t.setAlpha(dividerLeash, 1);
- t.setLayer(dividerLeash, Integer.MAX_VALUE);
- t.setPosition(dividerLeash,
- mSplitLayout.getRefDividerBounds().left,
- mSplitLayout.getRefDividerBounds().top);
+ final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+ mDividerFadeInAnimator = ValueAnimator.ofFloat(0f, 1f);
+ mDividerFadeInAnimator.addUpdateListener(animation -> {
+ if (dividerLeash == null) {
+ mDividerFadeInAnimator.cancel();
+ return;
+ }
+ transaction.setAlpha(dividerLeash, (float) animation.getAnimatedValue());
+ transaction.apply();
+ });
+ mDividerFadeInAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (dividerLeash == null) {
+ mDividerFadeInAnimator.cancel();
+ return;
+ }
+ transaction.show(dividerLeash);
+ transaction.setAlpha(dividerLeash, 0);
+ transaction.setLayer(dividerLeash, Integer.MAX_VALUE);
+ transaction.setPosition(dividerLeash,
+ mSplitLayout.getRefDividerBounds().left,
+ mSplitLayout.getRefDividerBounds().top);
+ transaction.apply();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mTransactionPool.release(transaction);
+ mDividerFadeInAnimator = null;
+ }
+ });
+
+ mDividerFadeInAnimator.start();
} else {
t.hide(dividerLeash);
}
@@ -1096,10 +1164,8 @@
mSplitLayout.init();
prepareEnterSplitScreen(wct);
mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t -> {
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
- setDividerVisibility(true, t);
- });
+ mSyncQueue.runInSync(t ->
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
}
if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
mShouldUpdateRecents = true;
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
index cf4ea46..41cd31a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/AppPairsHelper.kt
@@ -37,7 +37,7 @@
val displayBounds = WindowUtils.displayBounds
val secondaryAppBounds = Region.from(0,
dividerBounds.bounds.bottom - WindowUtils.dockedStackDividerInset,
- displayBounds.right, displayBounds.bottom - WindowUtils.navigationBarHeight)
+ displayBounds.right, displayBounds.bottom - WindowUtils.navigationBarFrameHeight)
return secondaryAppBounds
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
index a510d69..e2da1a4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
@@ -171,7 +171,7 @@
val bottomAppBounds = Region.from(0,
dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
displayBounds.right,
- displayBounds.bottom - WindowUtils.navigationBarHeight)
+ displayBounds.bottom - WindowUtils.navigationBarFrameHeight)
visibleRegion(Components.SimpleActivity.COMPONENT.toFlickerComponent())
.coversExactly(topAppBounds)
visibleRegion(Components.ImeActivity.COMPONENT.toFlickerComponent())
@@ -192,7 +192,7 @@
val bottomAppBounds = Region.from(0,
dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
displayBounds.right,
- displayBounds.bottom - WindowUtils.navigationBarHeight)
+ displayBounds.bottom - WindowUtils.navigationBarFrameHeight)
visibleRegion(Components.SimpleActivity.COMPONENT.toFlickerComponent())
.coversExactly(topAppBounds)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 6cf8829..42b1014 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -209,12 +209,11 @@
createNavigationInfo(animationTarget, null, null,
BackNavigationInfo.TYPE_RETURN_TO_HOME, null);
- // Check that back start is dispatched.
doMotionEvent(MotionEvent.ACTION_DOWN, 0);
- verify(mIOnBackInvokedCallback).onBackStarted();
- // Check that back progress is dispatched.
+ // Check that back start and progress is dispatched when first move.
doMotionEvent(MotionEvent.ACTION_MOVE, 100);
+ verify(mIOnBackInvokedCallback).onBackStarted();
ArgumentCaptor<BackEvent> backEventCaptor = ArgumentCaptor.forClass(BackEvent.class);
verify(mIOnBackInvokedCallback).onBackProgressed(backEventCaptor.capture());
assertEquals(animationTarget, backEventCaptor.getValue().getDepartingAnimationTarget());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 169f03e..bde94d9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -115,7 +115,7 @@
private ArgumentCaptor<BubbleData.Update> mUpdateCaptor;
@Mock
- private Bubbles.SuppressionChangedListener mSuppressionListener;
+ private Bubbles.BubbleMetadataFlagListener mBubbleMetadataFlagListener;
@Mock
private Bubbles.PendingIntentCanceledListener mPendingIntentCanceledListener;
@@ -136,30 +136,47 @@
mock(NotificationListenerService.Ranking.class);
when(ranking.isTextChanged()).thenReturn(true);
mEntryInterruptive = createBubbleEntry(1, "interruptive", "package.d", ranking);
- mBubbleInterruptive = new Bubble(mEntryInterruptive, mSuppressionListener, null,
+ mBubbleInterruptive = new Bubble(mEntryInterruptive, mBubbleMetadataFlagListener, null,
mMainExecutor);
mEntryDismissed = createBubbleEntry(1, "dismissed", "package.d", null);
- mBubbleDismissed = new Bubble(mEntryDismissed, mSuppressionListener, null,
+ mBubbleDismissed = new Bubble(mEntryDismissed, mBubbleMetadataFlagListener, null,
mMainExecutor);
mEntryLocusId = createBubbleEntry(1, "keyLocus", "package.e", null,
new LocusId("locusId1"));
- mBubbleLocusId = new Bubble(mEntryLocusId, mSuppressionListener, null, mMainExecutor);
+ mBubbleLocusId = new Bubble(mEntryLocusId,
+ mBubbleMetadataFlagListener,
+ null /* pendingIntentCanceledListener */,
+ mMainExecutor);
- mBubbleA1 = new Bubble(mEntryA1, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleA1 = new Bubble(mEntryA1,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleA2 = new Bubble(mEntryA2, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleA2 = new Bubble(mEntryA2,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleA3 = new Bubble(mEntryA3, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleA3 = new Bubble(mEntryA3,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleB1 = new Bubble(mEntryB1, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleB1 = new Bubble(mEntryB1,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleB2 = new Bubble(mEntryB2, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleB2 = new Bubble(mEntryB2,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleB3 = new Bubble(mEntryB3, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleB3 = new Bubble(mEntryB3,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
- mBubbleC1 = new Bubble(mEntryC1, mSuppressionListener, mPendingIntentCanceledListener,
+ mBubbleC1 = new Bubble(mEntryC1,
+ mBubbleMetadataFlagListener,
+ mPendingIntentCanceledListener,
mMainExecutor);
mPositioner = new TestableBubblePositioner(mContext,
mock(WindowManager.class));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index 819a984..e8f3f69 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -63,7 +63,7 @@
private Bubble mBubble;
@Mock
- private Bubbles.SuppressionChangedListener mSuppressionListener;
+ private Bubbles.BubbleMetadataFlagListener mBubbleMetadataFlagListener;
@Before
public void setUp() {
@@ -81,7 +81,7 @@
when(mNotif.getBubbleMetadata()).thenReturn(metadata);
when(mSbn.getKey()).thenReturn("mock");
mBubbleEntry = new BubbleEntry(mSbn, null, true, false, false, false);
- mBubble = new Bubble(mBubbleEntry, mSuppressionListener, null, mMainExecutor);
+ mBubble = new Bubble(mBubbleEntry, mBubbleMetadataFlagListener, null, mMainExecutor);
}
@Test
@@ -144,22 +144,22 @@
}
@Test
- public void testSuppressionListener_change_notified() {
+ public void testBubbleMetadataFlagListener_change_notified() {
assertThat(mBubble.showInShade()).isTrue();
mBubble.setSuppressNotification(true);
assertThat(mBubble.showInShade()).isFalse();
- verify(mSuppressionListener).onBubbleNotificationSuppressionChange(mBubble);
+ verify(mBubbleMetadataFlagListener).onBubbleMetadataFlagChanged(mBubble);
}
@Test
- public void testSuppressionListener_noChange_doesntNotify() {
+ public void testBubbleMetadataFlagListener_noChange_doesntNotify() {
assertThat(mBubble.showInShade()).isTrue();
mBubble.setSuppressNotification(false);
- verify(mSuppressionListener, never()).onBubbleNotificationSuppressionChange(any());
+ verify(mBubbleMetadataFlagListener, never()).onBubbleMetadataFlagChanged(any());
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 4b85496..e8e6254 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -21,10 +21,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -77,11 +79,11 @@
@Mock private PipUiEventLogger mMockPipUiEventLogger;
@Mock private Optional<SplitScreenController> mMockOptionalSplitScreen;
@Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
+ @Mock private PipParamsChangedForwarder mMockPipParamsChangedForwarder;
private TestShellExecutor mMainExecutor;
private PipBoundsState mPipBoundsState;
private PipTransitionState mPipTransitionState;
private PipBoundsAlgorithm mPipBoundsAlgorithm;
- private PipParamsChangedForwarder mPipParamsChangedForwarder;
private ComponentName mComponent1;
private ComponentName mComponent2;
@@ -100,7 +102,7 @@
mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
mPipBoundsAlgorithm, mMockPhonePipMenuController, mMockPipAnimationController,
mMockPipSurfaceTransactionHelper, mMockPipTransitionController,
- mPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController,
+ mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController,
mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor));
mMainExecutor.flushAll();
preparePipTaskOrg();
@@ -181,11 +183,12 @@
// It is in entering transition, should defer onTaskInfoChanged callback in this case.
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1,
createPipParams(newAspectRatio)));
- assertEquals(startAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f);
+ verify(mMockPipParamsChangedForwarder, never()).notifyAspectRatioChanged(anyFloat());
// Once the entering transition finishes, the new aspect ratio applies in a deferred manner
mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
- assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f);
+ verify(mMockPipParamsChangedForwarder)
+ .notifyAspectRatioChanged(newAspectRatio.floatValue());
}
@Test
@@ -199,7 +202,8 @@
mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1,
createPipParams(newAspectRatio)));
- assertEquals(newAspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f);
+ verify(mMockPipParamsChangedForwarder)
+ .notifyAspectRatioChanged(newAspectRatio.floatValue());
}
@Test
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 5368b7d..df18133 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
@@ -45,6 +45,7 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.onehanded.OneHandedController;
+import com.android.wm.shell.pip.PipAppOpsListener;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipBoundsState;
import com.android.wm.shell.pip.PipMediaController;
@@ -75,7 +76,6 @@
@Mock private PhonePipMenuController mMockPhonePipMenuController;
@Mock private PipAppOpsListener mMockPipAppOpsListener;
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
- @Mock private PipKeepClearAlgorithm mMockPipKeepClearAlgorithm;
@Mock private PipSnapAlgorithm mMockPipSnapAlgorithm;
@Mock private PipMediaController mMockPipMediaController;
@Mock private PipTaskOrganizer mMockPipTaskOrganizer;
@@ -100,12 +100,12 @@
return null;
}).when(mMockExecutor).execute(any());
mPipController = new PipController(mContext, mMockDisplayController,
- mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm,
- mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
+ mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
+ mMockPipBoundsState, mMockPipMediaController,
mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
mMockPipTransitionController, mMockWindowManagerShellWrapper,
- mMockTaskStackListener, mPipParamsChangedForwarder, mMockOneHandedController,
- mMockExecutor);
+ mMockTaskStackListener, mPipParamsChangedForwarder,
+ mMockOneHandedController, mMockExecutor);
when(mMockPipBoundsAlgorithm.getSnapAlgorithm()).thenReturn(mMockPipSnapAlgorithm);
when(mMockPipTouchHandler.getMotionHelper()).thenReturn(mMockPipMotionHelper);
}
@@ -133,12 +133,12 @@
when(spyContext.getPackageManager()).thenReturn(mockPackageManager);
assertNull(PipController.create(spyContext, mMockDisplayController,
- mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm,
- mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
+ mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
+ mMockPipBoundsState, mMockPipMediaController,
mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
mMockPipTransitionController, mMockWindowManagerShellWrapper,
- mMockTaskStackListener, mPipParamsChangedForwarder, mMockOneHandedController,
- mMockExecutor));
+ mMockTaskStackListener, mPipParamsChangedForwarder,
+ mMockOneHandedController, mMockExecutor));
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java
deleted file mode 100644
index f657b5e..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java
+++ /dev/null
@@ -1,96 +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.wm.shell.pip.phone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import android.graphics.Rect;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Set;
-
-/**
- * Unit tests against {@link PipKeepClearAlgorithm}.
- */
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class PipKeepClearAlgorithmTest extends ShellTestCase {
-
- private PipKeepClearAlgorithm mPipKeepClearAlgorithm;
-
-
- @Before
- public void setUp() throws Exception {
- mPipKeepClearAlgorithm = new PipKeepClearAlgorithm();
- }
-
- @Test
- public void adjust_withCollidingRestrictedKeepClearAreas_movesBounds() {
- final Rect inBounds = new Rect(0, 0, 100, 100);
- final Rect keepClearRect = new Rect(50, 50, 150, 150);
-
- final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect),
- Set.of());
-
- assertFalse(outBounds.contains(keepClearRect));
- }
-
- @Test
- public void adjust_withNonCollidingRestrictedKeepClearAreas_boundsDoNotChange() {
- final Rect inBounds = new Rect(0, 0, 100, 100);
- final Rect keepClearRect = new Rect(100, 100, 150, 150);
-
- final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect),
- Set.of());
-
- assertEquals(inBounds, outBounds);
- }
-
- @Test
- public void adjust_withCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() {
- // TODO(b/183746978): update this test to accommodate for the updated algorithm
- final Rect inBounds = new Rect(0, 0, 100, 100);
- final Rect keepClearRect = new Rect(50, 50, 150, 150);
-
- final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(),
- Set.of(keepClearRect));
-
- assertEquals(inBounds, outBounds);
- }
-
- @Test
- public void adjust_withNonCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() {
- final Rect inBounds = new Rect(0, 0, 100, 100);
- final Rect keepClearRect = new Rect(100, 100, 150, 150);
-
- final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(),
- Set.of(keepClearRect));
-
- assertEquals(inBounds, outBounds);
- }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index a55f737..ffaab65 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -139,6 +139,7 @@
}
@Test
+ @UiThreadTest
public void testLaunchToSide() {
ActivityManager.RunningTaskInfo newTask = new TestRunningTaskInfoBuilder()
.setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
@@ -173,6 +174,7 @@
}
@Test
+ @UiThreadTest
public void testLaunchPair() {
TransitionInfo info = createEnterPairInfo();
@@ -195,6 +197,7 @@
}
@Test
+ @UiThreadTest
public void testMonitorInSplit() {
enterSplit();
@@ -251,6 +254,7 @@
}
@Test
+ @UiThreadTest
public void testEnterRecents() {
enterSplit();
@@ -288,6 +292,7 @@
}
@Test
+ @UiThreadTest
public void testDismissFromBeingOccluded() {
enterSplit();
@@ -325,6 +330,7 @@
}
@Test
+ @UiThreadTest
public void testDismissFromMultiWindowSupport() {
enterSplit();
@@ -346,6 +352,7 @@
}
@Test
+ @UiThreadTest
public void testDismissSnap() {
enterSplit();
@@ -370,6 +377,7 @@
}
@Test
+ @UiThreadTest
public void testDismissFromAppFinish() {
enterSplit();
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index e7432ac..90c4440 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -136,24 +136,59 @@
free(valueBuffer);
return nullptr;
}
+ mNumShadersCachedInRam++;
+ ATRACE_FORMAT("HWUI RAM cache: %d shaders", mNumShadersCachedInRam);
return SkData::MakeFromMalloc(valueBuffer, valueSize);
}
+namespace {
+// Helper for BlobCache::set to trace the result.
+void set(BlobCache* cache, const void* key, size_t keySize, const void* value, size_t valueSize) {
+ switch (cache->set(key, keySize, value, valueSize)) {
+ case BlobCache::InsertResult::kInserted:
+ // This is what we expect/hope. It means the cache is large enough.
+ return;
+ case BlobCache::InsertResult::kDidClean: {
+ ATRACE_FORMAT("ShaderCache: evicted an entry to fit {key: %lu value %lu}!", keySize,
+ valueSize);
+ return;
+ }
+ case BlobCache::InsertResult::kNotEnoughSpace: {
+ ATRACE_FORMAT("ShaderCache: could not fit {key: %lu value %lu}!", keySize, valueSize);
+ return;
+ }
+ case BlobCache::InsertResult::kInvalidValueSize:
+ case BlobCache::InsertResult::kInvalidKeySize: {
+ ATRACE_FORMAT("ShaderCache: invalid size {key: %lu value %lu}!", keySize, valueSize);
+ return;
+ }
+ case BlobCache::InsertResult::kKeyTooBig:
+ case BlobCache::InsertResult::kValueTooBig:
+ case BlobCache::InsertResult::kCombinedTooBig: {
+ ATRACE_FORMAT("ShaderCache: entry too big: {key: %lu value %lu}!", keySize, valueSize);
+ return;
+ }
+ }
+}
+} // namespace
+
void ShaderCache::saveToDiskLocked() {
ATRACE_NAME("ShaderCache::saveToDiskLocked");
if (mInitialized && mBlobCache && mSavePending) {
if (mIDHash.size()) {
auto key = sIDKey;
- mBlobCache->set(&key, sizeof(key), mIDHash.data(), mIDHash.size());
+ set(mBlobCache.get(), &key, sizeof(key), mIDHash.data(), mIDHash.size());
}
mBlobCache->writeToFile();
}
mSavePending = false;
}
-void ShaderCache::store(const SkData& key, const SkData& data) {
+void ShaderCache::store(const SkData& key, const SkData& data, const SkString& /*description*/) {
ATRACE_NAME("ShaderCache::store");
std::lock_guard<std::mutex> lock(mMutex);
+ mNumShadersCachedInRam++;
+ ATRACE_FORMAT("HWUI RAM cache: %d shaders", mNumShadersCachedInRam);
if (!mInitialized) {
return;
@@ -187,7 +222,7 @@
mNewPipelineCacheSize = -1;
mTryToStorePipelineCache = true;
}
- bc->set(key.data(), keySize, value, valueSize);
+ set(bc, key.data(), keySize, value, valueSize);
if (!mSavePending && mDeferredSaveDelay > 0) {
mSavePending = true;
diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h
index 4dcc9fb..3e0fd51 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.h
+++ b/libs/hwui/pipeline/skia/ShaderCache.h
@@ -73,7 +73,7 @@
* "store" attempts to insert a new key/value blob pair into the cache.
* This will be called by Skia after it compiled a new SKSL shader
*/
- void store(const SkData& key, const SkData& data) override;
+ void store(const SkData& key, const SkData& data, const SkString& description) override;
/**
* "onVkFrameFlushed" tries to store Vulkan pipeline cache state.
@@ -210,6 +210,13 @@
*/
static constexpr uint8_t sIDKey = 0;
+ /**
+ * Most of this class concerns persistent storage for shaders, but it's also
+ * interesting to keep track of how many shaders are stored in RAM. This
+ * class provides a convenient entry point for that.
+ */
+ int mNumShadersCachedInRam = 0;
+
friend class ShaderCacheTestUtils; // used for unit testing
};
diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp
index 87981f1..974d85a 100644
--- a/libs/hwui/tests/unit/ShaderCacheTests.cpp
+++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp
@@ -140,9 +140,9 @@
// write to the in-memory cache without storing on disk and verify we read the same values
sk_sp<SkData> inVS;
setShader(inVS, "sassas");
- ShaderCache::get().store(GrProgramDescTest(100), *inVS.get());
+ ShaderCache::get().store(GrProgramDescTest(100), *inVS.get(), SkString());
setShader(inVS, "someVS");
- ShaderCache::get().store(GrProgramDescTest(432), *inVS.get());
+ ShaderCache::get().store(GrProgramDescTest(432), *inVS.get(), SkString());
ASSERT_NE((outVS = ShaderCache::get().load(GrProgramDescTest(100))), sk_sp<SkData>());
ASSERT_TRUE(checkShader(outVS, "sassas"));
ASSERT_NE((outVS = ShaderCache::get().load(GrProgramDescTest(432))), sk_sp<SkData>());
@@ -166,7 +166,7 @@
// change data, store to disk, read back again and verify data has been changed
setShader(inVS, "ewData1");
- ShaderCache::get().store(GrProgramDescTest(432), *inVS.get());
+ ShaderCache::get().store(GrProgramDescTest(432), *inVS.get(), SkString());
ShaderCacheTestUtils::terminate(ShaderCache::get(), true);
ShaderCache::get().initShaderDiskCache();
ASSERT_NE((outVS2 = ShaderCache::get().load(GrProgramDescTest(432))), sk_sp<SkData>());
@@ -177,7 +177,7 @@
std::vector<uint8_t> dataBuffer(dataSize);
genRandomData(dataBuffer);
setShader(inVS, dataBuffer);
- ShaderCache::get().store(GrProgramDescTest(432), *inVS.get());
+ ShaderCache::get().store(GrProgramDescTest(432), *inVS.get(), SkString());
ShaderCacheTestUtils::terminate(ShaderCache::get(), true);
ShaderCache::get().initShaderDiskCache();
ASSERT_NE((outVS2 = ShaderCache::get().load(GrProgramDescTest(432))), sk_sp<SkData>());
@@ -225,7 +225,7 @@
setShader(data, dataBuffer);
blob = std::make_pair(key, data);
- ShaderCache::get().store(*key.get(), *data.get());
+ ShaderCache::get().store(*key.get(), *data.get(), SkString());
}
ShaderCacheTestUtils::terminate(ShaderCache::get(), true);
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 1dc74e5..10ea651 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -106,6 +106,7 @@
PointerController::~PointerController() {
mDisplayInfoListener->onPointerControllerDestroyed();
mUnregisterWindowInfosListener(mDisplayInfoListener);
+ mContext.getPolicy()->onPointerDisplayIdChanged(ADISPLAY_ID_NONE, 0, 0);
}
std::mutex& PointerController::getLock() const {
@@ -255,6 +256,12 @@
getAdditionalMouseResources = true;
}
mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
+ if (viewport.displayId != mLocked.pointerDisplayId) {
+ float xPos, yPos;
+ mCursorController.getPosition(&xPos, &yPos);
+ mContext.getPolicy()->onPointerDisplayIdChanged(viewport.displayId, xPos, yPos);
+ mLocked.pointerDisplayId = viewport.displayId;
+ }
}
void PointerController::updatePointerIcon(int32_t iconId) {
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 2e6e851..eab030f 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -104,6 +104,7 @@
struct Locked {
Presentation presentation;
+ int32_t pointerDisplayId = ADISPLAY_ID_NONE;
std::vector<gui::DisplayInfo> mDisplayInfos;
std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers;
diff --git a/libs/input/PointerControllerContext.h b/libs/input/PointerControllerContext.h
index 26a65a4..c2bc1e0 100644
--- a/libs/input/PointerControllerContext.h
+++ b/libs/input/PointerControllerContext.h
@@ -79,6 +79,7 @@
std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0;
virtual int32_t getDefaultPointerIconId() = 0;
virtual int32_t getCustomPointerIconId() = 0;
+ virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0;
};
/*
diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp
index dae1fcc..f9752ed 100644
--- a/libs/input/tests/PointerController_test.cpp
+++ b/libs/input/tests/PointerController_test.cpp
@@ -56,9 +56,11 @@
std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) override;
virtual int32_t getDefaultPointerIconId() override;
virtual int32_t getCustomPointerIconId() override;
+ virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override;
bool allResourcesAreLoaded();
bool noResourcesAreLoaded();
+ std::optional<int32_t> getLastReportedPointerDisplayId() { return latestPointerDisplayId; }
private:
void loadPointerIconForType(SpriteIcon* icon, int32_t cursorType);
@@ -66,6 +68,7 @@
bool pointerIconLoaded{false};
bool pointerResourcesLoaded{false};
bool additionalMouseResourcesLoaded{false};
+ std::optional<int32_t /*displayId*/> latestPointerDisplayId;
};
void MockPointerControllerPolicyInterface::loadPointerIcon(SpriteIcon* icon, int32_t) {
@@ -126,12 +129,19 @@
icon->hotSpotX = hotSpot.first;
icon->hotSpotY = hotSpot.second;
}
+
+void MockPointerControllerPolicyInterface::onPointerDisplayIdChanged(int32_t displayId,
+ float /*xPos*/,
+ float /*yPos*/) {
+ latestPointerDisplayId = displayId;
+}
+
class PointerControllerTest : public Test {
protected:
PointerControllerTest();
~PointerControllerTest();
- void ensureDisplayViewportIsSet();
+ void ensureDisplayViewportIsSet(int32_t displayId = ADISPLAY_ID_DEFAULT);
sp<MockSprite> mPointerSprite;
sp<MockPointerControllerPolicyInterface> mPolicy;
@@ -168,9 +178,9 @@
mThread.join();
}
-void PointerControllerTest::ensureDisplayViewportIsSet() {
+void PointerControllerTest::ensureDisplayViewportIsSet(int32_t displayId) {
DisplayViewport viewport;
- viewport.displayId = ADISPLAY_ID_DEFAULT;
+ viewport.displayId = displayId;
viewport.logicalRight = 1600;
viewport.logicalBottom = 1200;
viewport.physicalRight = 800;
@@ -255,6 +265,30 @@
ensureDisplayViewportIsSet();
}
+TEST_F(PointerControllerTest, notifiesPolicyWhenPointerDisplayChanges) {
+ EXPECT_FALSE(mPolicy->getLastReportedPointerDisplayId())
+ << "A pointer display change does not occur when PointerController is created.";
+
+ ensureDisplayViewportIsSet(ADISPLAY_ID_DEFAULT);
+
+ const auto lastReportedPointerDisplayId = mPolicy->getLastReportedPointerDisplayId();
+ ASSERT_TRUE(lastReportedPointerDisplayId)
+ << "The policy is notified of a pointer display change when the viewport is first set.";
+ EXPECT_EQ(ADISPLAY_ID_DEFAULT, *lastReportedPointerDisplayId)
+ << "Incorrect pointer display notified.";
+
+ ensureDisplayViewportIsSet(42);
+
+ EXPECT_EQ(42, *mPolicy->getLastReportedPointerDisplayId())
+ << "The policy is notified when the pointer display changes.";
+
+ // Release the PointerController.
+ mPointerController = nullptr;
+
+ EXPECT_EQ(ADISPLAY_ID_NONE, *mPolicy->getLastReportedPointerDisplayId())
+ << "The pointer display changes to invalid when PointerController is destroyed.";
+}
+
class PointerControllerWindowInfoListenerTest : public Test {};
class TestPointerController : public PointerController {
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 70d6810..472586b 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -643,6 +643,9 @@
/**
* <p>Return the frame to the ImageReader for reuse.</p>
+ *
+ * This method should only be called via {@link SurfaceImage#close} which ensures that image
+ * closing is atomic.
*/
private void releaseImage(Image i) {
if (! (i instanceof SurfaceImage) ) {
@@ -1125,6 +1128,8 @@
}
private class SurfaceImage extends android.media.Image {
+ private final Object mCloseLock = new Object();
+
public SurfaceImage(int format) {
mFormat = format;
mHardwareBufferFormat = ImageReader.this.mHardwareBufferFormat;
@@ -1139,7 +1144,9 @@
@Override
public void close() {
- ImageReader.this.releaseImage(this);
+ synchronized (this.mCloseLock) {
+ ImageReader.this.releaseImage(this);
+ }
}
public ImageReader getReader() {
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index ef0270b..e5673a6 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -1728,7 +1728,9 @@
}
int res = nativeSetMaxNumberOfFrontends(frontendType, maxNumber);
if (res == RESULT_SUCCESS) {
- // TODO: b/211778848 Update Tuner Resource Manager.
+ if (!mTunerResourceManager.setMaxNumberOfFrontends(frontendType, maxNumber)) {
+ res = RESULT_INVALID_ARGUMENT;
+ }
}
return res;
}
@@ -1749,7 +1751,13 @@
TunerVersionChecker.TUNER_VERSION_2_0, "Set maximum Frontends")) {
return -1;
}
- return nativeGetMaxNumberOfFrontends(frontendType);
+ int maxNumFromHAL = nativeGetMaxNumberOfFrontends(frontendType);
+ int maxNumFromTRM = mTunerResourceManager.getMaxNumberOfFrontends(frontendType);
+ if (maxNumFromHAL != maxNumFromTRM) {
+ Log.w(TAG, "max num of usable frontend is out-of-sync b/w " + maxNumFromHAL
+ + " != " + maxNumFromTRM);
+ }
+ return maxNumFromHAL;
}
/** @hide */
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index 5ada89e..15175a7 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -401,6 +401,43 @@
}
/**
+ * Sets the maximum usable frontends number of a given frontend type. It is used to enable or
+ * disable frontends when cable connection status is changed by user.
+ *
+ * @param frontendType the frontendType which the maximum usable number will be set for.
+ * @param maxNum the new maximum usable number.
+ *
+ * @return true if successful and false otherwise.
+ */
+ public boolean setMaxNumberOfFrontends(int frontendType, int maxNum) {
+ boolean result = false;
+ try {
+ result = mService.setMaxNumberOfFrontends(frontendType, maxNum);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ return result;
+ }
+
+ /**
+ * Get the maximum usable frontends number of a given frontend type.
+ *
+ * @param frontendType the frontendType which the maximum usable number will be queried for.
+ *
+ * @return the maximum usable number of the queried frontend type. Returns -1 when the
+ * frontendType is invalid
+ */
+ public int getMaxNumberOfFrontends(int frontendType) {
+ int result = -1;
+ try {
+ result = mService.getMaxNumberOfFrontends(frontendType);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ return result;
+ }
+
+ /**
* Requests from the client to share frontend with an existing client.
*
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
diff --git a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
index d16fc6c..144b98c 100644
--- a/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
+++ b/media/java/android/media/tv/tunerresourcemanager/aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.aidl
@@ -166,6 +166,27 @@
boolean requestFrontend(in TunerFrontendRequest request, out int[] frontendHandle);
/*
+ * Sets the maximum usable frontends number of a given frontend type. It is used to enable or
+ * disable frontends when cable connection status is changed by user.
+ *
+ * @param frontendType the frontendType which the maximum usable number will be set for.
+ * @param maxNumber the new maximum usable number.
+ *
+ * @return true if successful and false otherwise.
+ */
+ boolean setMaxNumberOfFrontends(in int frontendType, in int maxNum);
+
+ /*
+ * Get the maximum usable frontends number of a given frontend type.
+ *
+ * @param frontendType the frontendType which the maximum usable number will be queried for.
+ *
+ * @return the maximum usable number of the queried frontend type. Returns -1 when the
+ * frontendType is invalid
+ */
+ int getMaxNumberOfFrontends(in int frontendType);
+
+ /*
* Requests to share frontend with an existing client.
*
* <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 8b5d214..16cd2e5 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -46,6 +46,7 @@
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+ android:configChanges="orientation|screenSize"
android:theme="@style/ChooserActivity"/>
<service
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml
new file mode 100644
index 0000000..8d7fa26
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ 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"
+ android:tint="@android:color/system_accent1_200">
+ <path
+ android:pathData="M6.2529,18.5H16.2529V17.5H18.2529V21.5C18.2529,22.6 17.3529,23.5 16.2529,23.5H6.2529C5.1529,23.5 4.2529,22.6 4.2529,21.5V3.5C4.2529,2.4 5.1529,1.51 6.2529,1.51L16.2529,1.5C17.3529,1.5 18.2529,2.4 18.2529,3.5V7.5H16.2529V6.5H6.2529V18.5ZM16.2529,3.5H6.2529V4.5H16.2529V3.5ZM6.2529,21.5V20.5H16.2529V21.5H6.2529ZM12.6553,9.4049C12.6553,8.8526 13.103,8.4049 13.6553,8.4049H20.5254C21.0776,8.4049 21.5254,8.8526 21.5254,9.4049V14.6055C21.5254,15.1578 21.0776,15.6055 20.5254,15.6055H14.355L12.6553,17.0871V9.4049Z"
+ android:fillColor="#3C4043"
+ android:fillType="evenOdd"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml
new file mode 100644
index 0000000..5689e34
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_info.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M11,17H13V11H11ZM12,9Q12.425,9 12.713,8.712Q13,8.425 13,8Q13,7.575 12.713,7.287Q12.425,7 12,7Q11.575,7 11.288,7.287Q11,7.575 11,8Q11,8.425 11.288,8.712Q11.575,9 12,9ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12ZM12,20Q15.325,20 17.663,17.663Q20,15.325 20,12Q20,8.675 17.663,6.337Q15.325,4 12,4Q8.675,4 6.338,6.337Q4,8.675 4,12Q4,15.325 6.338,17.663Q8.675,20 12,20Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml
new file mode 100644
index 0000000..06bfad5
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml
@@ -0,0 +1,26 @@
+<?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"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml
new file mode 100644
index 0000000..f8aef33
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml b/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml
index 8e92051f..6ce1f12 100644
--- a/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml
+++ b/packages/CompanionDeviceManager/res/drawable/helper_back_button.xml
@@ -18,6 +18,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/system_accent1_100"/>
- <corners android:topLeftRadius="16dp" android:topRightRadius="16dp"
- android:bottomLeftRadius="16dp" android:bottomRightRadius="16dp"/>
+ <corners android:topLeftRadius="20dp" android:topRightRadius="20dp"
+ android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp"/>
</shape>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
index d1ec863..7295e78 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_apps.xml
@@ -19,7 +19,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
- android:viewportHeight="24">
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_600">
<path
android:pathData="M6.2529,18.5H16.2529V17.5H18.2529V21.5C18.2529,22.6 17.3529,23.5 16.2529,23.5H6.2529C5.1529,23.5 4.2529,22.6 4.2529,21.5V3.5C4.2529,2.4 5.1529,1.51 6.2529,1.51L16.2529,1.5C17.3529,1.5 18.2529,2.4 18.2529,3.5V7.5H16.2529V6.5H6.2529V18.5ZM16.2529,3.5H6.2529V4.5H16.2529V3.5ZM6.2529,21.5V20.5H16.2529V21.5H6.2529ZM12.6553,9.4049C12.6553,8.8526 13.103,8.4049 13.6553,8.4049H20.5254C21.0776,8.4049 21.5254,8.8526 21.5254,9.4049V14.6055C21.5254,15.1578 21.0776,15.6055 20.5254,15.6055H14.355L12.6553,17.0871V9.4049Z"
android:fillColor="#3C4043"
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
index e5825bc..7b1ef85 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_600">
<path android:fillColor="@android:color/white"
android:pathData="M4,19V17H6V10Q6,7.925 7.25,6.312Q8.5,4.7 10.5,4.2V3.5Q10.5,2.875 10.938,2.438Q11.375,2 12,2Q12.625,2 13.062,2.438Q13.5,2.875 13.5,3.5V4.2Q15.5,4.7 16.75,6.312Q18,7.925 18,10V17H20V19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,22Q11.175,22 10.588,21.413Q10,20.825 10,20H14Q14,20.825 13.413,21.413Q12.825,22 12,22ZM8,17H16V10Q16,8.35 14.825,7.175Q13.65,6 12,6Q10.35,6 9.175,7.175Q8,8.35 8,10Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
index 406a3b5..3e033d3 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_storage.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_600">
<path android:fillColor="@android:color/white"
android:pathData="M6,17H18L14.25,12L11.25,16L9,13ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index c0e6c09..520ade8 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -12,135 +12,142 @@
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"
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:minWidth="340dp">
+ android:layout_height="match_parent"
+ style="@style/ScrollViewStyle">
- <LinearLayout android:id="@+id/association_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"
+ <LinearLayout
+ 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:baselineAligned="false">
- <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|end"
+ android:orientation="vertical"
+ android:layout_marginEnd="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="match_parent"
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:id="@+id/spinner_single_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>
+ style="@style/Spinner" />
+ </RelativeLayout>>
</LinearLayout>
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
-
- <ProgressBar
- android:id="@+id/spinner_single_device"
- android:visibility="gone"
- style="@style/Spinner" />
- </RelativeLayout>>
-
-</LinearLayout>
\ No newline at end of file
+</ScrollView>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
index a9ace44..d0d46f7 100644
--- a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
@@ -15,54 +15,67 @@
~ limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/helper_confirmation"
- android:theme="@style/ChooserActivity"
- android:padding="12dp"
- style="@style/ContainerLayout">
-
- <ImageView
- android:id="@+id/app_icon"
- android:layout_width="match_parent"
- android:layout_height="32dp"
- android:gravity="center"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"/>
-
- <TextView
- android:id="@+id/helper_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:paddingHorizontal="12dp"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="22sp" />
-
- <TextView
- android:id="@+id/helper_summary"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="24dp"
- android:gravity="center"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="14sp" />
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ style="@style/ScrollViewStyle">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginRight="12dp"
- android:layout_marginBottom="12dp"
- android:gravity="end">
+ android:layout_height="wrap_content">
- <Button
- android:id="@+id/btn_back"
- style="@style/VendorHelperBackButton"
- android:text="@string/consent_back" />
+ <LinearLayout
+ android:id="@+id/helper_confirmation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:theme="@style/ChooserActivity"
+ android:padding="12dp"
+ style="@style/ContainerLayout">
+
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:gravity="center"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"/>
+
+ <TextView
+ android:id="@+id/helper_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="22sp" />
+
+ <TextView
+ android:id="@+id/helper_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="32dp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textSize="14sp" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginEnd="12dp"
+ android:gravity="end">
+
+ <Button
+ android:id="@+id/btn_back"
+ style="@style/VendorHelperBackButton"
+ android:text="@string/consent_back" />
+
+ </LinearLayout>
+
+ </LinearLayout>
</LinearLayout>
-</LinearLayout>
\ No newline at end of file
+</ScrollView>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index eeb988f..0a5afe4 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -28,14 +28,15 @@
android:id="@android:id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="12dp"
+ android:layout_marginStart="24dp"
android:tint="@android:color/system_accent1_600"/>
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
index 3dce38d..54916a2 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -20,8 +20,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
+ android:paddingStart="32dp"
+ android:paddingEnd="32dp"
android:paddingBottom="14dp">
<ImageView
@@ -30,7 +30,6 @@
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
- android:tint="@android:color/system_accent1_600"
android:contentDescription="Permission Icon"/>
<LinearLayout
@@ -51,7 +50,6 @@
android:id="@+id/permission_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingRight="24dp"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"/>
diff --git a/packages/CompanionDeviceManager/res/layout/vendor_header.xml b/packages/CompanionDeviceManager/res/layout/vendor_header.xml
index c35f59e..14e7431 100644
--- a/packages/CompanionDeviceManager/res/layout/vendor_header.xml
+++ b/packages/CompanionDeviceManager/res/layout/vendor_header.xml
@@ -24,28 +24,32 @@
android:layout_gravity="center"
android:paddingTop="24dp"
android:paddingBottom="4dp"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
+ android:paddingStart="24dp"
+ android:paddingEnd="24dp"
android:visibility="gone" >
<ImageView
android:id="@+id/vendor_header_image"
- android:layout_width="31dp"
- android:layout_height="32dp" />
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:contentDescription="@string/vendor_icon_description" />
<TextView
android:id="@+id/vendor_header_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="20dp"
- android:layout_marginTop="5dp"
- android:layout_toRightOf="@+id/header_image" />
+ android:layout_marginStart="12dp"
+ android:layout_marginTop="12dp"
+ android:textSize="16sp"
+ android:layout_toEndOf="@+id/vendor_header_image"
+ android:textColor="?android:attr/textColorSecondary"/>
<ImageButton
android:id="@+id/vendor_header_button"
android:background="@drawable/ic_info"
- android:layout_width="31dp"
- android:layout_height="32dp"
- android:layout_alignParentRight="true" />
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:contentDescription="@string/vendor_header_button_description"
+ android:layout_alignParentEnd="true" />
</RelativeLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 3c71300..8c7fdfa 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -25,7 +25,7 @@
<string name="permission_apps" msgid="6142133265286656158">"ಆ್ಯಪ್ಗಳು"</string>
<string name="permission_apps_summary" msgid="798718816711515431">"ನಿಮ್ಮ ಫೋನ್ನ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string>
- <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಸಾಧನ ಸೇವೆಗಳು"</string>
+ <string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
<string name="helper_summary_app_streaming" msgid="7380294597268573523">"ನಿಮ್ಮ ಫೋನ್ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 586a022..3d6bf15 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -116,4 +116,10 @@
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\u2019s microphone and location.</string>
+ <!--Description for vendor icon [CHAR LIMIT=30]-->
+ <string name="vendor_icon_description">App Icon</string>
+
+ <!--Description for information icon [CHAR LIMIT=30]-->
+ <string name="vendor_header_button_description">More Information Button</string>
+
</resources>
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index c38323f..428f2dc 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -59,9 +59,8 @@
<style name="VendorHelperBackButton"
parent="@android:style/Widget.Material.Button.Borderless.Colored">
- <item name="android:layout_width">60dp</item>
- <item name="android:layout_height">36dp</item>
- <item name="android:layout_marginTop">20dp</item>
+ <item name="android:layout_width">70dp</item>
+ <item name="android:layout_height">48dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textColor">@android:color/system_neutral1_900</item>
<item name="android:background">@drawable/helper_back_button</item>
@@ -71,8 +70,6 @@
parent="@android:style/Widget.Material.Button.Borderless.Colored">
<item name="android:layout_width">300dp</item>
<item name="android:layout_height">56dp</item>
- <item name="android:layout_marginLeft">24dp</item>
- <item name="android:layout_marginRight">24dp</item>
<item name="android:layout_marginBottom">2dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
@@ -84,8 +81,6 @@
parent="@android:style/Widget.Material.Button.Borderless.Colored">
<item name="android:layout_width">300dp</item>
<item name="android:layout_height">56dp</item>
- <item name="android:layout_marginLeft">24dp</item>
- <item name="android:layout_marginRight">24dp</item>
<item name="android:layout_marginTop">2dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
@@ -115,4 +110,10 @@
<item name="android:indeterminate">true</item>
<item name="android:layout_centerInParent">true</item>
</style>
+
+ <style name="ScrollViewStyle">
+ <item name="android:scrollbars">none</item>
+ <item name="android:fillViewport">true</item>
+ <item name="android:clipChildren">false</item>
+ </style>
</resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/themes.xml b/packages/CompanionDeviceManager/res/values/themes.xml
index e3fc67c..1ea3968 100644
--- a/packages/CompanionDeviceManager/res/values/themes.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -18,8 +18,8 @@
<style name="ChooserActivity"
parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar">
- <item name="*android:windowFixedHeightMajor">100%</item>
- <item name="*android:windowFixedHeightMinor">100%</item>
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 37cbf30..9e9ec04 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -51,6 +51,7 @@
import android.companion.IAssociationRequestCallback;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.net.MacAddress;
import android.os.Bundle;
@@ -411,17 +412,19 @@
final Drawable vendorIcon;
final CharSequence vendorName;
final Spanned title;
+ int nightModeFlags = getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
mPermissionTypes = new ArrayList<>();
try {
vendorIcon = getVendorHeaderIcon(this, packageName, userId);
vendorName = getVendorHeaderName(this, packageName, userId);
-
mVendorHeaderImage.setImageDrawable(vendorIcon);
if (hasVendorIcon(this, packageName, userId)) {
- mVendorHeaderImage.setColorFilter(getResources().getColor(
- android.R.color.system_accent1_600, /* Theme= */null));
+ int color = nightModeFlags == Configuration.UI_MODE_NIGHT_YES
+ ? android.R.color.system_accent1_200 : android.R.color.system_accent1_600;
+ mVendorHeaderImage.setColorFilter(getResources().getColor(color, /* Theme= */null));
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Package u" + userId + "/" + packageName + " not found.");
@@ -484,6 +487,14 @@
if (deviceFilterPairs.isEmpty()) return;
mSelectedDevice = requireNonNull(deviceFilterPairs.get(0));
+ // No need to show user consent dialog if it is a singleDevice
+ // and isSkipPrompt(true) AssociationRequest.
+ // See AssociationRequestsProcessor#mayAssociateWithoutPrompt.
+ if (mRequest.isSkipPrompt()) {
+ mSingleDeviceSpinner.setVisibility(View.GONE);
+ onUserSelectedDevice(mSelectedDevice);
+ return;
+ }
final String deviceName = mSelectedDevice.getDisplayName();
final Spanned title = getHtmlFromResources(
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
index e8a1a5c..f333b86 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
@@ -150,8 +150,6 @@
mBtAdapter = mBtManager.getAdapter();
mBleScanner = mBtAdapter.getBluetoothLeScanner();
mWifiManager = getSystemService(WifiManager.class);
-
- sScanResultsLiveData.setValue(Collections.emptyList());
}
@Override
@@ -175,6 +173,7 @@
@Override
public void onDestroy() {
+ sScanResultsLiveData.setValue(Collections.emptyList());
super.onDestroy();
if (DEBUG) Log.d(TAG, "onDestroy()");
}
@@ -188,6 +187,7 @@
mStopAfterFirstMatch = request.isSingleDevice();
mDiscoveryStarted = true;
sStateLiveData.setValue(DiscoveryState.DISCOVERY_IN_PROGRESS);
+ sScanResultsLiveData.setValue(Collections.emptyList());
final List<DeviceFilter<?>> allFilters = request.getDeviceFilters();
final List<BluetoothDeviceFilter> btFilters =
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index aa21b4f..fac338b 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -84,7 +84,7 @@
<string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak tableta honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
<string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
<string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan. Hori aldatzeko, joan Ezarpenak atalera."</string>
- <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+ <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Baliteke telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jasatea. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoari agian gertatuko zaizkion kalteen edo datu-galeren erantzulea."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index d8f54e9..93f37bf 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -84,9 +84,9 @@
<string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"За ваша безбедност, таблетот нема дозвола за инсталирање непознати апликации од изворов во моментов. Ова може да го промените во „Поставки“."</string>
<string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"За ваша безбедност, телевизорот нема дозвола за инсталирање непознати апликации од изворов во моментов. Ова може да го промените во „Поставки“."</string>
<string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"За ваша безбедност, телефонот нема дозвола за инсталирање непознати апликации од изворов во моментов. Ова може да го промените во „Поставки“."</string>
- <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телефонот или губењето податоци што може да произлезат од нејзиното користење."</string>
- <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблетот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на таблетот или губењето податоци што може да произлезат од нејзиното користење."</string>
- <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Телевизорот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телевизорот или губењето податоци што може да произлезат од нејзиното користење."</string>
+ <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонот и личните податоци се поподложни на напади од апликации од непознати извори. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телефонот или загуба на податоци поради нејзиното користење."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблетот и личните податоци се поподложни на напади од апликации од непознати извори. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на таблетот или загуба на податоци поради нејзиното користење."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Телевизорот и личните податоци се поподложни на напади од апликации од непознати извори. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телевизорот или загуба на податоци поради нејзиното користење."</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Продолжи"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Поставки"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Се инсталираат/деинсталираат аплик. Wear"</string>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
index 25f0771..72b569f 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
@@ -25,7 +25,7 @@
android:fitsSystemWindows="true"
android:outlineAmbientShadowColor="@android:color/transparent"
android:outlineSpotShadowColor="@android:color/transparent"
- android:background="?android:attr/colorPrimary"
+ android:background="@android:color/transparent"
android:theme="@style/Theme.CollapsingToolbar.Settings">
<com.google.android.material.appbar.CollapsingToolbarLayout
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
index 72383fe..dbb4b50 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayout.java
@@ -20,6 +20,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
+import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -29,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
@@ -41,6 +43,7 @@
* This widget is wrapping the collapsing toolbar and can be directly used by the
* {@link AppCompatActivity}.
*/
+@RequiresApi(Build.VERSION_CODES.S)
public class CollapsingCoordinatorLayout extends CoordinatorLayout {
private static final String TAG = "CollapsingCoordinatorLayout";
private static final float TOOLBAR_LINE_SPACING_MULTIPLIER = 1.1f;
diff --git a/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml b/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
index 212ae52..42700b3 100644
--- a/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
+++ b/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
@@ -60,6 +60,7 @@
android:text="@string/settingslib_learn_more_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingBottom="8dp"
android:clickable="true"
android:visibility="gone"
style="@style/TextAppearance.Footer.Title.SettingsLib"/>
diff --git a/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml b/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
index d403f9e..1adcead 100644
--- a/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
+++ b/packages/SettingsLib/FooterPreference/res/layout/preference_footer.xml
@@ -59,6 +59,7 @@
android:text="@string/settingslib_learn_more_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingBottom="8dp"
android:clickable="true"
android:visibility="gone"
style="@style/TextAppearance.Footer.Title.SettingsLib"/>
diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
index ac30636..6766cdd 100644
--- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
+++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
@@ -40,6 +40,8 @@
static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
@VisibleForTesting
View.OnClickListener mLearnMoreListener;
+ @VisibleForTesting
+ int mIconVisibility = View.VISIBLE;
private CharSequence mContentDescription;
private CharSequence mLearnMoreText;
private CharSequence mLearnMoreContentDescription;
@@ -84,6 +86,9 @@
} else {
learnMore.setVisibility(View.GONE);
}
+
+ View icon = holder.itemView.findViewById(R.id.icon_frame);
+ icon.setVisibility(mIconVisibility);
}
@Override
@@ -165,6 +170,17 @@
}
}
+ /**
+ * Set visibility of footer icon.
+ */
+ public void setIconVisibility(int iconVisibility) {
+ if (mIconVisibility == iconVisibility) {
+ return;
+ }
+ mIconVisibility = iconVisibility;
+ notifyChanged();
+ }
+
private void init() {
setLayoutResource(R.layout.preference_footer);
if (getIcon() == null) {
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
index f57061a..4fc4ab4 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"વ્યવસ્થાપકે ચાલુ કરેલ"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"વ્યવસ્થાપકે બંધ કરેલું"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"ઍડમિને બંધ કરેલું"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml
index fd4f856..007de06 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-iw/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"מופעל על ידי מנהל המכשיר"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"הושבת על ידי מנהל המכשיר"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"האפשרות הושבתה על ידי האדמין"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml
index 9c225f9..d01bfc4 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-mr/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"अॅडमिनने सुरू केलेले"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"प्रशासकाने बंद केलेले"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"अॅडमिनने बंद केलेले"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml
index 2c37652..dd654b2 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-vi/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"Do quản trị viên bật"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"Đã bị quản trị viên vô hiệu hóa"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"Quản trị viên đã vô hiệu hóa chế độ này"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 36eb472..121402c 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Budíky a připomenutí"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Povolit nastavování budíků a připomenutí"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a připomenutí"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povolte aplikaci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud je toto oprávnění vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Když tuto možnost povolíte, aplikace bude moci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud toto oprávnění zůstane vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, připomenutí, hodiny"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnout"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapněte funkci Nerušit"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 74e2dbb..1dc7b42 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -528,7 +528,7 @@
<string name="done" msgid="381184316122520313">"Done"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index eacaad0..20e9308 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -528,7 +528,7 @@
<string name="done" msgid="381184316122520313">"Done"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 74e2dbb..1dc7b42 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -528,7 +528,7 @@
<string name="done" msgid="381184316122520313">"Done"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 74e2dbb..1dc7b42 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -528,7 +528,7 @@
<string name="done" msgid="381184316122520313">"Done"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarms and reminders"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Allow setting alarms and reminders"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms & reminders"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index e635464..9cdcc1c 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser à définir des alarmes et des rappels"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autoriser cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index c1c23a5..3ab01369 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म और रिमाइंडर"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म और रिमाइंडर सेट करने की अनुमति दें"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म और रिमाइंडर"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nअगर आप यह अनुमति नहीं देते हैं, तो इस ऐप्लिकेशन की मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nऐप्लिकेशन को यह अनुमति न देने पर, इसकी मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index f48af46..e7c0a3b 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Զարթուցիչներ և հիշեցումներ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Թույլատրել զարթուցիչների և հիշեցումների սահմանումը"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Զարթուցիչներ և հիշեցումներ"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրեք այս հավելվածին դնել զարթուցիչներ և ստեղծել գործողությունների կատարման ժամանակացույցներ։ Այդպես հավելվածը կկարողանա աշխատել ֆոնային ռեժիմում, ինչի արդյունքում ավելի շատ մարտկոցի լիցք կսպառվի։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և միջոցառումների ժամանակացույցները չեն աշխատի։"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրել այս հավելվածին զարթուցիչներ կարգավորել և որոշակի ժամանակի համար գործողություններ պլանավորել։ Այդ դեպքում հավելվածն աշխատում է ֆոնային ռեժիմում, և արդյունքում մարտկոցի լիցքն ավելի արագ է սպառվում։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և գործողությունների ժամանակացույցները չեն աշխատի։"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ժամանակացույց, զարթուցիչ, հիշեցում, ժամացույց"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index ca9649d..f04a394 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Sveglie e promemoria"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Consenti l\'impostazione di sveglie e promemoria"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Sveglie e promemoria"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per le quali il fattore temporale è decisivo. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per orari specifici. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programmare, sveglia, promemoria, orologio"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Attiva"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Attiva Non disturbare"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index b97deca..e42dcbd 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Оятқыш және еске салғыш"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Оятқыштар мен еске салғыштарды орнатуға рұқсат беру"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Оятқыштар мен еске салғыштар"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа негізделген әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа негізделген іс-шаралар жұмыс істемейді."</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа байланысты әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа байланысты іс-шаралар жұмыс істемейді."</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"кесте, оятқыш, еске салғыш, сағат"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Қосу"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Мазаламау режимін қосу"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 7a97242..53b4017 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -151,7 +151,7 @@
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"취소"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"페어링하면 연결 시 연락처 및 통화 기록에 액세스할 수 있습니다."</string>
<string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와 페어링하지 못했습니다."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 통신할 수 없습니다."</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 페어링을 거부했습니다."</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"컴퓨터"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 711a8f1..4e86795 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -528,7 +528,7 @@
<string name="done" msgid="381184316122520313">"सम्पन्न भयो"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म र रिमाइन्डरहरू"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म तथा रिमाइन्डर सेट गर्न दिइयोस्"</string>
- <string name="alarms_and_reminders_title" msgid="8819933264635406032">"घडी तथा रिमाइन्डरहरू"</string>
+ <string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म तथा रिमाइन्डर"</string>
<string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन बनाउने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा चल्छ र धेरै ब्याट्री खपत हुन्छ।\n\nयो अनुमति दिइएको छैन भने सेट गरिएका अलार्म बज्दैनन् र यो एपले तय गरेका गतिविधि चल्दैनन्।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"अन गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index a4e2aa7..6449971 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ ਸੈੱਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 4a1186e..454867e 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -217,7 +217,7 @@
<item msgid="2464080977843960236">"Animație la scara 10x"</item>
</string-array>
<string-array name="overlay_display_devices_entries">
- <item msgid="4497393944195787240">"Niciuna"</item>
+ <item msgid="4497393944195787240">"Fără"</item>
<item msgid="8461943978957133391">"480p"</item>
<item msgid="6923083594932909205">"480p (securizat)"</item>
<item msgid="1226941831391497335">"720p"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 0cb9c84..4e01d61 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -491,7 +491,7 @@
<string name="disabled" msgid="8017887509554714950">"අබල කර ඇත"</string>
<string name="external_source_trusted" msgid="1146522036773132905">"ඉඩ දුන්"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"ඉඩ නොදෙන"</string>
- <string name="install_other_apps" msgid="3232595082023199454">"නොදන්නා යෙදුම් ස්ථාප."</string>
+ <string name="install_other_apps" msgid="3232595082023199454">"නොදන්නා යෙදුම් ස්ථාපනය"</string>
<string name="home" msgid="973834627243661438">"සැකසීම් මුල් පිටුව"</string>
<string-array name="battery_labels">
<item msgid="7878690469765357158">"0%"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index fd7c893..3280e4f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -589,7 +589,7 @@
<string name="add_user_failed" msgid="4809887794313944872">"Imeshindwa kuweka mtumiaji mpya"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Imeshindwa kuunda wasifu mpya wa mgeni"</string>
<string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string>
- <string name="user_add_user" msgid="7876449291500212468">"Weka mtumiaji"</string>
+ <string name="user_add_user" msgid="7876449291500212468">"Ongeza mtumiaji"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string>
<string name="guest_reset_guest" msgid="6110013010356013758">"Badilisha kipindi cha mgeni"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 8c3d6f3..f31fde6 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -224,7 +224,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"เลือกโปรไฟล์"</string>
<string name="category_personal" msgid="6236798763159385225">"ส่วนตัว"</string>
- <string name="category_work" msgid="4014193632325996115">"ที่ทำงาน"</string>
+ <string name="category_work" msgid="4014193632325996115">"งาน"</string>
<string name="development_settings_title" msgid="140296922921597393">"ตัวเลือกสำหรับนักพัฒนาแอป"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 6652e08..3056ef7 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -529,7 +529,7 @@
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"الارمز اور یاد دہانیاں"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"الارمز اور یاد دہانیاں سیٹ کرنے کی اجازت دیں"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"الارمز اور یاد دہانیاں"</string>
- <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"اس ایپ کو الارمز سیٹ کرنے اور متعین وقت کے لحاظ سے حساس کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ یہ ایپ کو پس منظر میں چلنے دیتا ہے، جس میں زیادہ بیٹری استعمال ہو سکتی ہے۔\n\n اگر یہ اجازت آف ہے تو موجودہ الارمز اور اس ایپ کے ذریعے شیڈول کردہ وقت پر مبنی ایونٹس کام نہیں کریں گے۔"</string>
+ <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"اس ایپ کو الارمز سیٹ کرنے اور وقت کے لحاظ سے حساس کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس سے ایپ کو پس منظر میں چلنے کی اجازت ملتی ہے، جس میں زیادہ بیٹری استعمال ہو سکتی ہے۔\n\n اگر یہ اجازت آف ہے تو موجودہ الارمز اور اس ایپ کے ذریعے شیڈول کردہ وقت پر مبنی ایونٹس کام نہیں کریں گے۔"</string>
<string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"شیڈول، الارم، یاد دہانی، گھڑی"</string>
<string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"آن کریں"</string>
<string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ڈسٹرب نہ کریں\' کو آن کریں"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 284da73..2f30baa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -234,5 +234,10 @@
if (!(mPreference instanceof RestrictedTopLevelPreference)) {
mPreference.setEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
}
+
+ if (mPreference instanceof PrimarySwitchPreference) {
+ ((PrimarySwitchPreference) mPreference)
+ .setSwitchEnabled(!(mDisabledByAdmin || mDisabledByAppOps));
+ }
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index bdeb474..e6160bb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -16,10 +16,14 @@
package com.android.settingslib;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY;
+
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.annotation.NonNull;
import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Process;
@@ -37,6 +41,8 @@
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
+import com.android.settingslib.utils.BuildCompatUtils;
+
/**
* Version of SwitchPreference that can be disabled by a device admin
* using a user restriction.
@@ -117,8 +123,13 @@
CharSequence switchSummary;
if (mRestrictedSwitchSummary == null) {
- switchSummary = getContext().getText(isChecked()
- ? R.string.enabled_by_admin : R.string.disabled_by_admin);
+ switchSummary = isChecked()
+ ? getUpdatableEnterpriseString(
+ getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY,
+ R.string.enabled_by_admin)
+ : getUpdatableEnterpriseString(
+ getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY,
+ R.string.disabled_by_admin);
} else {
switchSummary = mRestrictedSwitchSummary;
}
@@ -153,6 +164,16 @@
}
}
+ private static String getUpdatableEnterpriseString(
+ Context context, String updatableStringId, int resId) {
+ if (!BuildCompatUtils.isAtLeastT()) {
+ return context.getString(resId);
+ }
+ return context.getSystemService(DevicePolicyManager.class).getResources().getString(
+ updatableStringId,
+ () -> context.getString(resId));
+ }
+
@Override
public void performClick() {
if (!mHelper.performClick()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index fdb0607..6b9daa3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -863,6 +863,30 @@
}
}
+ /**
+ * Activate session to enable a class that implements Callbacks to receive the callback.
+ */
+ public void activateSession() {
+ synchronized (mEntriesMap) {
+ if (!mResumed) {
+ mResumed = true;
+ mSessionsChanged = true;
+ }
+ }
+ }
+
+ /**
+ * Deactivate session to disable a class that implements Callbacks to get the callback.
+ */
+ public void deactivateSession() {
+ synchronized (mEntriesMap) {
+ if (mResumed) {
+ mResumed = false;
+ mSessionsChanged = true;
+ }
+ }
+ }
+
public ArrayList<AppEntry> getAllApps() {
synchronized (mEntriesMap) {
return new ArrayList<>(mAppEntries);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 4ee2122..6919cf2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1376,7 +1376,7 @@
/**
* Store the member devices that are in the same coordinated set.
*/
- public void setMemberDevice(CachedBluetoothDevice memberDevice) {
+ public void addMemberDevice(CachedBluetoothDevice memberDevice) {
mMemberDevices.add(memberDevice);
}
@@ -1393,24 +1393,24 @@
* device and member devices.
*
* @param prevMainDevice the previous Main device, it will be added into the member device set.
- * @param newMainDevie the new Main device, it will be removed from the member device set.
+ * @param newMainDevice the new Main device, it will be removed from the member device set.
*/
public void switchMemberDeviceContent(CachedBluetoothDevice prevMainDevice,
- CachedBluetoothDevice newMainDevie) {
+ CachedBluetoothDevice newMainDevice) {
// Backup from main device
final BluetoothDevice tmpDevice = mDevice;
final short tmpRssi = mRssi;
final boolean tmpJustDiscovered = mJustDiscovered;
// Set main device from sub device
- mDevice = newMainDevie.mDevice;
- mRssi = newMainDevie.mRssi;
- mJustDiscovered = newMainDevie.mJustDiscovered;
- setMemberDevice(prevMainDevice);
- mMemberDevices.remove(newMainDevie);
+ mDevice = newMainDevice.mDevice;
+ mRssi = newMainDevice.mRssi;
+ mJustDiscovered = newMainDevice.mJustDiscovered;
+ addMemberDevice(prevMainDevice);
+ mMemberDevices.remove(newMainDevice);
// Set sub device from backup
- newMainDevie.mDevice = tmpDevice;
- newMainDevie.mRssi = tmpRssi;
- newMainDevie.mJustDiscovered = tmpJustDiscovered;
+ newMainDevice.mDevice = tmpDevice;
+ newMainDevice.mRssi = tmpRssi;
+ newMainDevice.mJustDiscovered = tmpJustDiscovered;
fetchActiveDevices();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index cc56a21..89e10c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -85,7 +85,7 @@
// Once there is other devices with the same groupId, to add new device as member
// devices.
if (CsipDevice != null) {
- CsipDevice.setMemberDevice(newDevice);
+ CsipDevice.addMemberDevice(newDevice);
newDevice.setName(CsipDevice.getName());
return true;
}
@@ -148,7 +148,7 @@
log("onGroupIdChanged: removed from UI device =" + cachedDevice
+ ", with groupId=" + groupId + " firstMatchedIndex=" + firstMatchedIndex);
- mainDevice.setMemberDevice(cachedDevice);
+ mainDevice.addMemberDevice(cachedDevice);
mCachedDevices.remove(i);
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
break;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index c248fff..b0392be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -26,6 +26,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
+import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.Context;
@@ -202,6 +203,43 @@
mService.startSearchingForSources(filters);
}
+ /**
+ * Return true if a search has been started by this application.
+ *
+ * @return true if a search has been started by this application
+ * @hide
+ */
+ public boolean isSearchInProgress() {
+ if (DEBUG) {
+ Log.d(TAG, "isSearchInProgress()");
+ }
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
+ return false;
+ }
+ return mService.isSearchInProgress();
+ }
+
+ /**
+ * Get information about all Broadcast Sources that a Broadcast Sink knows about.
+ *
+ * @param sink Broadcast Sink from which to get all Broadcast Sources
+ * @return the list of Broadcast Receive State {@link BluetoothLeBroadcastReceiveState}
+ * stored in the Broadcast Sink
+ * @throws NullPointerException when <var>sink</var> is null
+ */
+ public @NonNull List<BluetoothLeBroadcastReceiveState> getAllSources(
+ @NonNull BluetoothDevice sink) {
+ if (DEBUG) {
+ Log.d(TAG, "getAllSources()");
+ }
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
+ return new ArrayList<BluetoothLeBroadcastReceiveState>();
+ }
+ return mService.getAllSources(sink);
+ }
+
public void registerServiceCallBack(@NonNull @CallbackExecutor Executor executor,
@NonNull BluetoothLeBroadcastAssistant.Callback callback) {
if (mService == null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
index 5b1fefb..aff9a6e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
@@ -25,6 +25,7 @@
import android.bluetooth.BluetoothLeBroadcastSubgroup;
import android.util.Log;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -95,6 +96,7 @@
}
public String convertToQrCodeString() {
+ String subgroupString = convertSubgroupToString(mSubgroupList);
return new StringBuilder()
.append(BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA)
.append(BluetoothBroadcastUtils.PREFIX_BT_ADDRESS_TYPE)
@@ -122,11 +124,83 @@
.append(METADATA_START).append(mPresentationDelayMicros).append(METADATA_END)
.append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
.append(BluetoothBroadcastUtils.PREFIX_BT_SUBGROUPS)
- .append(METADATA_START).append(mSubgroupList).append(METADATA_END)
+ .append(METADATA_START).append(subgroupString).append(METADATA_END)
.append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
.toString();
}
+ private String convertSubgroupToString(List<BluetoothLeBroadcastSubgroup> subgroupList) {
+ StringBuilder subgroupListBuilder = new StringBuilder();
+ String subgroupString = "";
+ for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
+ String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
+ String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
+ String channels = convertChannelToString(subgroup.getChannels());
+ subgroupString = new StringBuilder()
+ .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
+ .append(METADATA_START).append(subgroup.getCodecId()).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_CONFIG)
+ .append(METADATA_START).append(audioCodec).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
+ .append(METADATA_START).append(audioContent).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
+ .append(METADATA_START).append(channels).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .toString();
+ subgroupListBuilder.append(subgroupString);
+ }
+ return subgroupListBuilder.toString();
+ }
+
+ private String convertAudioCodecConfigToString(BluetoothLeAudioCodecConfigMetadata config) {
+ String audioLocation = String.valueOf(config.getAudioLocation());
+ String rawMetadata = new String(config.getRawMetadata(), StandardCharsets.UTF_8);
+ return new StringBuilder()
+ .append(BluetoothBroadcastUtils.PREFIX_BTCC_AUDIO_LOCATION)
+ .append(METADATA_START).append(audioLocation).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTCC_RAW_METADATA)
+ .append(METADATA_START).append(rawMetadata).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .toString();
+ }
+
+ private String convertAudioContentToString(BluetoothLeAudioContentMetadata audioContent) {
+ String rawMetadata = new String(audioContent.getRawMetadata(), StandardCharsets.UTF_8);
+ return new StringBuilder()
+ .append(BluetoothBroadcastUtils.PREFIX_BTAC_PROGRAM_INFO)
+ .append(METADATA_START).append(audioContent.getProgramInfo()).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTAC_LANGUAGE)
+ .append(METADATA_START).append(audioContent.getLanguage()).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTAC_RAW_METADATA)
+ .append(METADATA_START).append(rawMetadata).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .toString();
+ }
+
+ private String convertChannelToString(List<BluetoothLeBroadcastChannel> channelList) {
+ StringBuilder channelListBuilder = new StringBuilder();
+ String channelString = "";
+ for (BluetoothLeBroadcastChannel channel: channelList) {
+ String channelAudioCodec = convertAudioCodecConfigToString(channel.getCodecMetadata());
+ channelString = new StringBuilder()
+ .append(BluetoothBroadcastUtils.PREFIX_BTBC_CHANNEL_INDEX)
+ .append(METADATA_START).append(channel.getChannelIndex()).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .append(BluetoothBroadcastUtils.PREFIX_BTBC_CODEC_CONFIG)
+ .append(METADATA_START).append(channelAudioCodec).append(METADATA_END)
+ .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+ .toString();
+ channelListBuilder.append(channelString);
+ }
+ return channelListBuilder.toString();
+ }
+
/**
* Example : prefix is with the “BT:”, and end by the Android Version.
* BT:T:<1>;D:<00:11:22:AA:BB:CC>;AS:<1>;B:…;V:T;;
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index 20fe495..988055e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -1,9 +1,13 @@
package com.android.settingslib.core;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
@@ -16,9 +20,12 @@
private static final String TAG = "AbstractPrefController";
protected final Context mContext;
+ private final DevicePolicyManager mDevicePolicyManager;
public AbstractPreferenceController(Context context) {
mContext = context;
+ mDevicePolicyManager =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
}
/**
@@ -102,4 +109,40 @@
public CharSequence getSummary() {
return null;
}
+
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ protected void replaceEnterpriseStringTitle(PreferenceScreen screen,
+ String preferenceKey, String overrideKey, int resource) {
+ if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+ return;
+ }
+
+ Preference preference = screen.findPreference(preferenceKey);
+ if (preference == null) {
+ Log.d(TAG, "Could not find enterprise preference " + preferenceKey);
+ return;
+ }
+
+ preference.setTitle(
+ mDevicePolicyManager.getResources().getString(overrideKey,
+ () -> mContext.getString(resource)));
+ }
+
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+ protected void replaceEnterpriseStringSummary(
+ PreferenceScreen screen, String preferenceKey, String overrideKey, int resource) {
+ if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+ return;
+ }
+
+ Preference preference = screen.findPreference(preferenceKey);
+ if (preference == null) {
+ Log.d(TAG, "Could not find enterprise preference " + preferenceKey);
+ return;
+ }
+
+ preference.setSummary(
+ mDevicePolicyManager.getResources().getString(overrideKey,
+ () -> mContext.getString(resource)));
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
index 1b63e3e..1b0738f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
@@ -16,12 +16,16 @@
package com.android.settingslib;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyResourcesManager;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
@@ -30,7 +34,6 @@
import androidx.preference.PreferenceViewHolder;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -45,6 +48,10 @@
@Mock
private Preference mPreference;
@Mock
+ private DevicePolicyManager mDevicePolicyManager;
+ @Mock
+ private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
+ @Mock
private RestrictedTopLevelPreference mRestrictedTopLevelPreference;
private PreferenceViewHolder mViewHolder;
@@ -53,18 +60,22 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ doReturn(mDevicePolicyResourcesManager).when(mDevicePolicyManager)
+ .getResources();
+ doReturn(mDevicePolicyManager).when(mContext)
+ .getSystemService(DevicePolicyManager.class);
mViewHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
mHelper = new RestrictedPreferenceHelper(mContext, mPreference, null);
}
@Test
- @Ignore
public void bindPreference_disabled_shouldDisplayDisabledSummary() {
final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
when(mViewHolder.itemView.findViewById(android.R.id.summary))
.thenReturn(summaryView);
when(summaryView.getContext().getText(R.string.disabled_by_admin_summary_text))
.thenReturn("test");
+ when(mDevicePolicyResourcesManager.getString(any(), any())).thenReturn("test");
mHelper.useAdminDisabledSummary(true);
mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin());
@@ -75,13 +86,13 @@
}
@Test
- @Ignore
public void bindPreference_notDisabled_shouldNotHideSummary() {
final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
when(mViewHolder.itemView.findViewById(android.R.id.summary))
.thenReturn(summaryView);
when(summaryView.getContext().getText(R.string.disabled_by_admin_summary_text))
.thenReturn("test");
+ when(mDevicePolicyResourcesManager.getString(any(), any())).thenReturn("test");
when(summaryView.getText()).thenReturn("test");
mHelper.useAdminDisabledSummary(true);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 298ee90..bef1d9c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -40,7 +40,6 @@
import org.robolectric.RuntimeEnvironment;
import java.util.Collection;
-import java.util.HashMap;
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
@@ -503,8 +502,8 @@
CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3);
- cachedDevice1.setMemberDevice(cachedDevice2);
- cachedDevice1.setMemberDevice(cachedDevice3);
+ cachedDevice1.addMemberDevice(cachedDevice2);
+ cachedDevice1.addMemberDevice(cachedDevice3);
assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice2);
assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice3);
@@ -524,7 +523,7 @@
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
cachedDevice1.setGroupId(1);
cachedDevice2.setGroupId(1);
- cachedDevice1.setMemberDevice(cachedDevice2);
+ cachedDevice1.addMemberDevice(cachedDevice2);
// Call onDeviceUnpaired for the one in mCachedDevices.
mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
@@ -541,7 +540,7 @@
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
cachedDevice1.setGroupId(1);
cachedDevice2.setGroupId(1);
- cachedDevice1.setMemberDevice(cachedDevice2);
+ cachedDevice1.addMemberDevice(cachedDevice2);
// Call onDeviceUnpaired for the one in mCachedDevices.
mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
index 61a28aa..9abb27e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.view.LayoutInflater;
+import android.view.View;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
@@ -61,7 +62,7 @@
mFooterPreference.onBindViewHolder(holder);
assertThat(((TextView) holder.findViewById(
- R.id.settingslib_learn_more)).getText().toString())
+ R.id.settingslib_learn_more)).getText().toString())
.isEqualTo("Custom learn more");
}
@@ -86,4 +87,11 @@
assertThat(mFooterPreference.mLearnMoreListener).isNotNull();
}
+
+ @Test
+ public void setIconVisibility_shouldReturnSameVisibilityType() {
+ mFooterPreference.setIconVisibility(View.GONE);
+
+ assertThat(mFooterPreference.mIconVisibility).isEqualTo(View.GONE);
+ }
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 3029781..5eaf553 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -120,6 +120,9 @@
Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
+ Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS,
+ Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
Settings.Secure.VR_DISPLAY_MODE,
Settings.Secure.NOTIFICATION_BADGING,
Settings.Secure.NOTIFICATION_DISMISS_RTL,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index a4da497..9ee7b65 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -18,6 +18,7 @@
import static android.provider.settings.validators.SettingsValidators.ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
+import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.BOOLEAN_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.COLON_SEPARATED_COMPONENT_LIST_VALIDATOR;
import static android.provider.settings.validators.SettingsValidators.COLON_SEPARATED_PACKAGE_LIST_VALIDATOR;
@@ -176,6 +177,10 @@
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_WAKE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, ANY_STRING_VALIDATOR);
+ VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+ ANY_STRING_VALIDATOR);
VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 077337c..a6edb0f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -818,6 +818,13 @@
getContext().enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
"Access files from the settings of another user");
}
+ final String callingPackage = getCallingPackage();
+ if (mode.contains("w") && !Settings.checkAndNoteWriteSettingsOperation(getContext(),
+ Binder.getCallingUid(), callingPackage, getCallingAttributionTag(),
+ true /* throwException */)) {
+ Slog.e(LOG_TAG, "Package: " + callingPackage + " is not allowed to modify "
+ + "system settings files.");
+ }
uri = ContentProvider.getUriWithoutUserId(uri);
final String cacheRingtoneSetting;
@@ -5502,16 +5509,7 @@
currentVersion = 209;
}
if (currentVersion == 209) {
- // Version 209: Enable enforcement of
- // android.Manifest.permission#POST_NOTIFICATIONS in order for applications
- // to post notifications.
- final SettingsState secureSettings = getSecureSettingsLocked(userId);
- secureSettings.insertSettingLocked(
- Secure.NOTIFICATION_PERMISSION_ENABLED,
- /* enabled= */ "1",
- /* tag= */ null,
- /* makeDefault= */ false,
- SettingsState.SYSTEM_PACKAGE_NAME);
+ // removed now that feature is enabled for everyone
currentVersion = 210;
}
diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml
index 9694999..c4baa52 100644
--- a/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/dimens.xml
@@ -22,6 +22,4 @@
<!-- Overload default clock widget parameters -->
<dimen name="widget_big_font_size">88dp</dimen>
- <dimen name="qs_panel_padding_top">16dp</dimen>
-
-</resources>
\ No newline at end of file
+</resources>
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
index c1e81ba..b71caef 100644
--- a/packages/SystemUI/res-product/values/strings.xml
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -130,4 +130,8 @@
<!-- Text shown when viewing global actions while phone is locked and additional controls are hidden [CHAR LIMIT=NONE] -->
<string name="global_action_lock_message" product="device">Unlock your device for more options</string>
+ <!-- Text informing the user that their media is now playing on this device. [CHAR LIMIT=50] -->
+ <string name="media_transfer_playing_this_device" product="default">Playing on this phone</string>
+ <!-- Text informing the user that their media is now playing on this tablet device. [CHAR LIMIT=50] -->
+ <string name="media_transfer_playing_this_device" product="tablet">Playing on this tablet</string>
</resources>
diff --git a/packages/SystemUI/res/drawable/media_output_icon_volume.xml b/packages/SystemUI/res/drawable/media_output_icon_volume.xml
new file mode 100644
index 0000000..fce4e00
--- /dev/null
+++ b/packages/SystemUI/res/drawable/media_output_icon_volume.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@color/media_dialog_item_main_content"
+ android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.125,8.475 15.812,9.575Q16.5,10.675 16.5,12Q16.5,13.325 15.812,14.4Q15.125,15.475 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/qs_media_outline_album_bg.xml b/packages/SystemUI/res/drawable/qs_media_outline_album_bg.xml
new file mode 100644
index 0000000..ecd3876
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_media_outline_album_bg.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#FFFFFFFF" />
+ <corners android:radius="@dimen/notification_corner_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/qs_media_outline_layout_bg.xml b/packages/SystemUI/res/drawable/qs_media_outline_layout_bg.xml
new file mode 100644
index 0000000..4ba45c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_media_outline_layout_bg.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#00000000" />
+ <corners android:radius="@dimen/notification_corner_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/qs_media_scrim.xml b/packages/SystemUI/res/drawable/qs_media_scrim.xml
index 2ec319c..159414d 100644
--- a/packages/SystemUI/res/drawable/qs_media_scrim.xml
+++ b/packages/SystemUI/res/drawable/qs_media_scrim.xml
@@ -16,7 +16,6 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <corners android:radius="@dimen/notification_corner_radius"/>
<!-- gradient from 25% in the center to 100% at edges -->
<gradient
android:type="radial"
diff --git a/packages/SystemUI/res/layout/alert_dialog_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
index 528f603..fd06238 100644
--- a/packages/SystemUI/res/layout/alert_dialog_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-
<!--
- ~ Copyright (C) 2021 The Android Open Source Project
+ ~ 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.
@@ -15,88 +14,83 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<androidx.core.widget.NestedScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <com.android.internal.widget.AlertDialogLayout
- android:id="@*android:id/parentPanel"
+<com.android.internal.widget.AlertDialogLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@*android:id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal|top"
+ android:orientation="vertical"
+ android:paddingTop="@dimen/dialog_top_padding"
+>
+
+ <include layout="@layout/alert_dialog_title_systemui" />
+
+ <FrameLayout
+ android:id="@*android:id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_horizontal|top"
- android:orientation="vertical"
- android:paddingTop="@dimen/dialog_top_padding"
- >
+ android:minHeight="48dp"
+ android:paddingStart="@dimen/dialog_side_padding"
+ android:paddingEnd="@dimen/dialog_side_padding"
+ >
- <include layout="@layout/alert_dialog_title_systemui" />
-
- <FrameLayout
- android:id="@*android:id/contentPanel"
+ <ScrollView
+ android:id="@*android:id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="48dp"
- android:paddingStart="@dimen/dialog_side_padding"
- android:paddingEnd="@dimen/dialog_side_padding"
- >
+ android:clipToPadding="false">
- <ScrollView
- android:id="@*android:id/scrollView"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:clipToPadding="false">
+ android:orientation="vertical">
- <LinearLayout
+ <Space
+ android:id="@*android:id/textSpacerNoTitle"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="0dp" />
+
+ <TextView
+ android:id="@*android:id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ style="@style/TextAppearance.Dialog.Body.Message" />
- <Space
- android:id="@*android:id/textSpacerNoTitle"
- android:visibility="gone"
- android:layout_width="match_parent"
- android:layout_height="0dp" />
+ <Space
+ android:id="@*android:id/textSpacerNoButtons"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="6dp" />
+ </LinearLayout>
+ </ScrollView>
+ </FrameLayout>
- <TextView
- android:id="@*android:id/message"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.Dialog.Body.Message" />
-
- <Space
- android:id="@*android:id/textSpacerNoButtons"
- android:visibility="gone"
- android:layout_width="match_parent"
- android:layout_height="6dp" />
- </LinearLayout>
- </ScrollView>
- </FrameLayout>
+ <FrameLayout
+ android:id="@*android:id/customPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:paddingStart="@dimen/dialog_side_padding"
+ android:paddingEnd="@dimen/dialog_side_padding"
+ >
<FrameLayout
- android:id="@*android:id/customPanel"
+ android:id="@*android:id/custom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/dialog_side_padding"
+ android:paddingEnd="@dimen/dialog_side_padding">
+ <include
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="48dp"
- android:paddingStart="@dimen/dialog_side_padding"
- android:paddingEnd="@dimen/dialog_side_padding"
- >
-
- <FrameLayout
- android:id="@*android:id/custom"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </FrameLayout>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/dialog_side_padding"
- android:paddingEnd="@dimen/dialog_side_padding">
- <include
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- layout="@layout/alert_dialog_button_bar_systemui" />
- </FrameLayout>
- </com.android.internal.widget.AlertDialogLayout>
-
-</androidx.core.widget.NestedScrollView>
\ No newline at end of file
+ layout="@layout/alert_dialog_button_bar_systemui" />
+ </FrameLayout>
+</com.android.internal.widget.AlertDialogLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index b230438..085a581 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -67,7 +67,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="@dimen/overlay_offset_x"
- android:layout_marginBottom="@dimen/overlay_offset_y"
+ android:layout_marginBottom="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@id/actions_container_background"
android:elevation="7dp"
@@ -121,6 +121,30 @@
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/hidden_text_preview"
+ android:visibility="gone"
+ android:textFontWeight="500"
+ android:padding="8dp"
+ android:gravity="center"
+ android:textSize="14sp"
+ android:text="@string/clipboard_text_hidden"
+ android:textColor="?attr/overlayButtonTextColor"
+ android:background="?androidprv:attr/colorAccentSecondary"
+ android:layout_width="@dimen/clipboard_preview_size"
+ android:layout_height="@dimen/clipboard_preview_size"/>
+ <TextView
+ android:id="@+id/hidden_image_preview"
+ android:visibility="gone"
+ android:textFontWeight="500"
+ android:padding="8dp"
+ android:gravity="center"
+ android:textSize="14sp"
+ android:text="@string/clipboard_text_hidden"
+ android:textColor="#ffffff"
+ android:background="#000000"
+ android:layout_width="@dimen/clipboard_preview_size"
+ android:layout_height="@dimen/clipboard_preview_size"/>
</FrameLayout>
<FrameLayout
android:id="@+id/dismiss_button"
@@ -141,4 +165,4 @@
android:layout_margin="@dimen/overlay_dismiss_button_margin"
android:src="@drawable/overlay_cancel"/>
</FrameLayout>
-</com.android.systemui.screenshot.DraggableConstraintLayout>
+</com.android.systemui.screenshot.DraggableConstraintLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/fgs_manager_app_item.xml b/packages/SystemUI/res/layout/fgs_manager_app_item.xml
index 30bce9d..a6f659d 100644
--- a/packages/SystemUI/res/layout/fgs_manager_app_item.xml
+++ b/packages/SystemUI/res/layout/fgs_manager_app_item.xml
@@ -50,7 +50,8 @@
<Button
android:id="@+id/fgs_manager_app_item_stop_button"
android:layout_width="wrap_content"
- android:layout_height="48dp"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
android:text="@string/fgs_manager_app_item_stop_button_label"
android:layout_marginStart="12dp"
style="?android:attr/buttonBarNeutralButtonStyle" />
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 534c80d..0e20fa3 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -25,7 +25,8 @@
android:clipToPadding="true"
android:gravity="center_horizontal|fill_vertical"
android:forceHasOverlappingRendering="false"
- android:background="@drawable/qs_media_background"
+ android:background="@drawable/qs_media_outline_layout_bg"
+ android:clipToOutline="true"
android:theme="@style/MediaPlayer">
<ImageView
@@ -40,8 +41,8 @@
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:clipToOutline="true"
+ android:background="@drawable/qs_media_outline_album_bg"
android:foreground="@drawable/qs_media_scrim"
- android:background="@drawable/qs_media_scrim"
/>
<!-- Guideline for output switcher -->
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml
index 98804fc..c366ceb 100644
--- a/packages/SystemUI/res/layout/qs_paged_page.xml
+++ b/packages/SystemUI/res/layout/qs_paged_page.xml
@@ -19,7 +19,7 @@
android:id="@+id/tile_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingStart="@dimen/notification_side_paddings"
- android:paddingEnd="@dimen/notification_side_paddings"
+ android:paddingStart="@dimen/qs_tiles_page_horizontal_margin"
+ android:paddingEnd="@dimen/qs_tiles_page_horizontal_margin"
android:clipChildren="false"
android:clipToPadding="false" />
diff --git a/packages/SystemUI/res/layout/screenshot.xml b/packages/SystemUI/res/layout/screenshot.xml
index 890dbe5..c29e11b 100644
--- a/packages/SystemUI/res/layout/screenshot.xml
+++ b/packages/SystemUI/res/layout/screenshot.xml
@@ -29,18 +29,11 @@
android:clickable="true"
android:importantForAccessibility="no"/>
<ImageView
- android:id="@+id/screenshot_actions_background"
- android:layout_height="@dimen/overlay_bg_protection_height"
- android:layout_width="match_parent"
- android:layout_gravity="bottom"
- android:alpha="0.0"
- android:src="@drawable/overlay_actions_background_protection"/>
- <ImageView
android:id="@+id/screenshot_flash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
- android:elevation="@dimen/overlay_preview_elevation"
+ android:elevation="7dp"
android:src="@android:color/white"/>
<com.android.systemui.screenshot.ScreenshotSelectorView
android:id="@+id/screenshot_selector"
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index c60609b..9c02749 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -24,7 +24,7 @@
android:visibility="gone"
android:layout_height="0dp"
android:layout_width="0dp"
- android:elevation="1dp"
+ android:elevation="4dp"
android:background="@drawable/action_chip_container_background"
android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
app:layout_constraintBottom_toBottomOf="@+id/actions_container"
@@ -36,9 +36,10 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
+ android:layout_marginBottom="4dp"
android:paddingEnd="@dimen/overlay_action_container_padding_right"
android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
- android:elevation="1dp"
+ android:elevation="4dp"
android:scrollbars="none"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="1.0"
@@ -64,8 +65,8 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="@dimen/overlay_offset_x"
- android:layout_marginBottom="@dimen/overlay_offset_y"
- android:elevation="@dimen/overlay_preview_elevation"
+ android:layout_marginBottom="12dp"
+ android:elevation="7dp"
android:alpha="0"
android:background="@drawable/overlay_border"
app:layout_constraintStart_toStartOf="parent"
@@ -93,7 +94,7 @@
android:layout_margin="@dimen/overlay_border_width"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:elevation="@dimen/overlay_preview_elevation"
+ android:elevation="7dp"
android:contentDescription="@string/screenshot_edit_description"
android:scaleType="fitEnd"
android:background="@drawable/overlay_preview_background"
@@ -108,7 +109,7 @@
android:id="@+id/screenshot_dismiss_button"
android:layout_width="@dimen/overlay_dismiss_button_tappable_size"
android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
- android:elevation="@dimen/overlay_dismiss_button_elevation"
+ android:elevation="10dp"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/screenshot_preview"
app:layout_constraintEnd_toEndOf="@id/screenshot_preview"
@@ -130,5 +131,5 @@
android:visibility="gone"
app:layout_constraintStart_toStartOf="@id/screenshot_preview"
app:layout_constraintTop_toTopOf="@id/screenshot_preview"
- android:elevation="@dimen/overlay_preview_elevation"/>
+ android:elevation="7dp"/>
</com.android.systemui.screenshot.DraggableConstraintLayout>
diff --git a/packages/SystemUI/res/layout/scrollable_alert_dialog_systemui.xml b/packages/SystemUI/res/layout/scrollable_alert_dialog_systemui.xml
new file mode 100644
index 0000000..71bb938
--- /dev/null
+++ b/packages/SystemUI/res/layout/scrollable_alert_dialog_systemui.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<androidx.core.widget.NestedScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <include layout="@layout/alert_dialog_systemui" />
+
+</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index a32914a..94a7e94 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer weer skermkiekie neem"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan nie skermkiekie stoor nie"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Wysig"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Wysig skermkiekie"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Deel skermskoot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> besit hierdie toestel en kan netwerkverkeer monitor"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Hierdie toestel word verskaf deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is gekoppel aan die internet deur <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Hierdie toestel behoort aan jou organisasie"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Hierdie toestel behoort aan jou organisasie en is gekoppel aan die internet deur VPN\'e"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en is gekoppel aan die internet deur VPN\'e"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jou organisasie kan netwerkverkeer in jou werkprofiel monitor"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan netwerkverkeer in jou werkprofiel monitor"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Jou IT-admin kan netwerkaktiwiteit op jou werkprofiel sien"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netwerk kan gemonitor word"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Hierdie toestel is gekoppel aan die internet deur VPN\'e."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Jou werkprogramme is deur <xliff:g id="VPN_APP">%1$s</xliff:g> aan die internet gekoppel"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Jou persoonlike programme is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Hierdie toestel is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Hierdie toestel word verskaf deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Toestelbestuur"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"\'n Sertifikaatoutoriteit is op hierdie toestel geïnstalleer. Jou veilige netwerkverkeer kan gemonitor of gewysig word."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Jou administrateur het netwerkloginskrywing aangeskakel, wat verkeer op jou toestel monitor."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Jou administrateur het netwerkloglêers aangeskakel wat verkeer in jou werkprofiel monitor, maar nie in jou persoonlike profiel nie."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Hierdie toestel is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>. Jou IT-admin kan jou netwerkaktiwiteit sien, insluitend jou e-posse en blaaierdata."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Hierdie toestel is gekoppel aan die internet deur <xliff:g id="VPN_APP_0">%1$s</xliff:g> en <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Jou IT-admin kan jou netwerkaktiwiteit sien, insluitend jou e-posse en blaaierdata."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Jou werkprogramme is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>. Jou IT-admin en VPN-verskaffer kan jou netwerkaktiwiteit in werkprogramme sien, insluitend jou e-posse en blaaierdata."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Jou persoonlike programme is gekoppel aan die internet deur <xliff:g id="VPN_APP">%1$s</xliff:g>. Jou VPN-verskaffer kan jou netwerkaktiwiteit sien, insluitend jou e-posse en blaaierdata."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Maak VPN-instellings oop"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Hierdie toestel word deur jou ouer bestuur. Jou ouer kan inligting sien en bestuur soos die programme wat jy gebruik, jou ligging en jou skermtyd."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Skakel aan wanneer battery waarskynlik sal leegloop"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nee, dankie"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Stort SysUI-hoop"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programme gebruik tans jou <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Uitsaainaam"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Wagwoord"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Stoor"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Begin tans …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan nie uitsaai nie"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 660c8bd..a4d75b1 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ቅጽበታዊ ገጽ ዕይታን እንደገና ማንሳት ይሞክሩ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ቅጽበታዊ ገጽ እይታን ማስቀመጥ አልተቻለም"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"አርትዕ ያድርጉ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ቅጽበታዊ ገጽ ዕይታን አርትዕ ያድርጉ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ቅጽበታዊ ገጽ እይታን ያጋሩ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚቀርብ ነው"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ይህ መሣሪያ የድርጅትዎ ሲሆን በ <xliff:g id="VPN_APP">%1$s</xliff:g>በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ይህ መሳሪያ ንብረትነቱ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ሲሆን በ <xliff:g id="VPN_APP">%2$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ይህ መሣሪያ የድርጅትዎ ነው"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ይህ መሳሪያ ንብረትነቱ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ነው"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ይህ መሣሪያ የድርጅትዎ ሲሆን በVPNs በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ይህ መሣሪያ ንብረትነቱ የ<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ሲሆን በ VPNs በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"የእርስዎ ድርጅት በእርስዎ የሥራ መገለጫ ያለን የአውታረ መረብ ትራፊክን ሊቆጣጠር ይችል ይሆናል"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> በእርስዎ የሥራ መገለጫ ውስጥ የአውታረ መረብ ትራፊክ ላይ ክትትል ሊያደርግ ይችላል"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"የስራ መገለጫ አውታረ መረብ እንቅስቃሴ ለአይቲ አስተዳዳሪዎ ይታያል"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"አውታረ መረብ ክትትል የሚደረግበት ሊሆን ይችላል"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ይህ መሣሪያ በVPNs በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"የእርስዎ የስራ መተግበሪያዎች በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝተዋል"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"የእርስዎ ግላዊ መተግበሪያዎች በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝተዋል"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ይህ መሣሪያ በ <xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝቷል"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚቀርብ ነው"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"የመሣሪያ አስተዳደር"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"የእውቅና ማረጋገጫ ሰጪ ባለሥልጣን በዚህ መሣሪያ ላይ ተጭኗል። የእርስዎ ደኅንነቱ የተጠበቀ አውታረ መረብ ትራፊክ ክትትል ሊደረግበት እና ሊሻሻል ይችላል።"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"የእርስዎ አስተዳዳሪ የአውታረ መረብ ምዝግብ ማስታወሻ መያዝን አብርተዋል፣ ይህም በመሣሪያዎ ላይ ያለውን ትራፊክ ይከታተላል።"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"የእርስዎ አስተዳዳሪ በስራ መገለጫዎ ውስጥ፣ ግን በግል መገለጫዎ ላይ ሳይሆን፣ ትራፊክን የሚቆጣጠር የአውታረ መረብ ምዝግብ ማስታወሻ አብርተዋል።"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ይህ መሣሪያ በ <xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝቷል። ኢሜይሎችን እና የአሰሳ ውሂብን ጨምሮ የእርስዎ የአውታረ መረብ እንቅስቃሴ ለአይቲ አስተዳዳሪዎ ይታያል።"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ይህ መሣሪያ በ <xliff:g id="VPN_APP_0">%1$s</xliff:g> እና <xliff:g id="VPN_APP_1">%2$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝቷል። ኢሜይሎችን እና የአሰሳ ውሂብን ጨምሮ የእርስዎ የአውታረ መረብ እንቅስቃሴ ለአይቲ አስተዳዳሪዎ ይታያል።"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"የእርስዎ የሥራ መተግበሪያዎች በ <xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝተዋል። ኢሜይሎችን እና የአሰሳ ውሂብን ጨምሮ በሥራ መተግበሪያዎች ውስጥ ያለው የአውታረ መረብ እንቅስቃሴዎ ለአይቲ አስተዳዳሪዎ እና ለVPN አቅራቢዎ ይታያል።"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"የእርስዎ ግላዊ መተግበሪያዎች በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል ከበይነመረብ ጋር ተገናኝተዋል። ኢሜይሎችን እና የአሰሳ ውሂብን ጨምሮ የአውታረ መረብ እንቅስቃሴዎ ለVPN አቅራቢዎ ይታያል።"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"የቪፒኤን ቅንብሮችን ይክፈቱ"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው። ወላጅዎ የሚጠቀሙባቸውን መተግበሪያዎች፣ አካባቢዎን እና የማያ ገጽ ጊዜዎን የመሳሰሉ መረጃዎችን ማየት እና ማስተዳደር ይችላል።"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ባትሪው የማለቅ ዕድሉ ከፍ ያለ ከሆነ ያብሩት"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"አይ፣ አመሰግናለሁ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Heap አራግፍ"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"መተግበሪያዎች የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> እየተጠቀሙ ነው።"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"፣ "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" እና "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"የስርጭት ስም"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"የይለፍ ቃል"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"አስቀምጥ"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"በመጀመር ላይ…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"መሰራጨት አይችልም"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index e7befd4..60d2680 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"جرّب أخذ لقطة الشاشة مرة أخرى"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"يتعذّر حفظ لقطة الشاشة."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"يحظر التطبيق أو تحظر مؤسستك التقاط لقطات شاشة"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"تعديل"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"تعديل لقطة الشاشة"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"مشاركة لقطة الشاشة"</string>
@@ -377,28 +379,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"تملك مؤسستك هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"تملك مؤسسة <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"توفر مؤسسة \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\" هذا الجهاز."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ينتمي هذا الجهاز إلى مؤسستك، ويتّصل بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ينتمي هذا الجهاز إلى <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>، ويتّصل بالإنترنت من خلال <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"هذا الجهاز يخص مؤسستك."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ينتمي هذا الجهاز إلى مؤسستك، ويتّصل بالإنترنت من خلال خدمات الشبكة الافتراضية الخاصة (VPN)."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ينتمي هذا الجهاز إلى <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>، ويتّصل بالإنترنت من خلال خدمات الشبكة الافتراضية الخاصة (VPN)."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"يمكن لمؤسستك مراقبة حركة بيانات الشبكة في الملف الشخصي للعمل"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"يمكن لـ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> مراقبة حركة بيانات الشبكة في ملفك الشخصي للعمل"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"تكون أنشطة شبكة الملف الشخصي للعمل مرئية لمشرف تكنولوجيا المعلومات."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"قد تكون الشبكة خاضعة للمراقبة"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"هذا الجهاز متّصل بالإنترنت من خلال خدمات الشبكات الافتراضية الخاصة (VPN)."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"تطبيقات العمل الخاصة بك متّصلة بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"تطبيقاتك الشخصية متّصلة بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"هذا الجهاز متّصل بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"توفر مؤسسة \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\" هذا الجهاز"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"إدارة الأجهزة"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"شبكة افتراضية خاصة (VPN)"</string>
@@ -414,14 +408,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"تم تثبيت مرجع مصدّق على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات على جهازك."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات في ملفك الشخصي للعمل ولكن لا تتم مراقبتها في ملفك الشخصي."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"هذا الجهاز متّصل بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>. تظهر أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، لمشرف تكنولوجيا المعلومات."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"هذا الجهاز متّصل بالإنترنت من خلال <xliff:g id="VPN_APP_0">%1$s</xliff:g> و<xliff:g id="VPN_APP_1">%2$s</xliff:g>. تظهر أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، لمشرف تكنولوجيا المعلومات."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"تطبيقات العمل الخاصة بك متّصلة بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>. تظهر أنشطة الشبكة في تطبيقات العمل، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، لمشرف تكنولوجيا المعلومات ومزوّد خدمة الشبكة الافتراضية الخاصة (VPN)."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"تطبيقاتك الشخصية متّصلة بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>. تظهر أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، لمزوّد خدمة الشبكة الافتراضية الخاصة (VPN)."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"فتح إعدادات الشبكة الافتراضية الخاصة (VPN)"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"يتولّى أحد الوالدين إدارة هذا الجهاز. يمكن للوالدين عرض وإدارة معلوماتك، مثلاً التطبيقات التي تستخدمها وموقعك الجغرافي ووقت النظر إلى الشاشة."</string>
@@ -750,6 +740,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"فعِّل الميزة إذا كان من المرجح نفاد شحن البطارية."</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"لا، شكرًا"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"تفريغ ذاكرة SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
@@ -879,9 +871,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"اسم البث"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"كلمة المرور"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"حفظ"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"جارٍ البدء…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"يتعذّر البث"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index f8b7b2e..8d2a9b2 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"স্ক্ৰীণশ্বট আকৌ ল\'বলৈ চেষ্টা কৰক"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"স্ক্ৰীনশ্বট ছেভ কৰিব নোৱাৰি"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"এপটোৱে বা আপোনাৰ প্ৰতিষ্ঠানে স্ক্ৰীণশ্বট ল\'বলৈ অনুমতি নিদিয়ে"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"সম্পাদনা কৰক"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্ৰীনশ্বট সম্পাদনা কৰক"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্ৰীনশ্বট শ্বেয়াৰ কৰক"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইচটোৰ গৰাকী আপোনাৰ প্ৰতিষ্ঠান আৰু ই নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"এই ডিভাইচটোৰ গৰাকী <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আৰু এইটোৱে নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>এ প্ৰদান কৰিছে"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ আৰু এইটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ আৰু এইটো <xliff:g id="VPN_APP">%2$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ আৰু এইটো ভিপিএনৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ৰ আৰু এইটো ভিপিএনৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলৰ নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলৰ নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"কৰ্মস্থানৰ প্ৰ’ফাইলৰ নেটৱৰ্কৰ কাৰ্যকলাপ আপোনাৰ আইটি প্ৰশাসকৰ বাবে দৃশ্যমান হয়"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"এই ডিভাইচটো ভিপিএনৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"আপোনাৰ কৰ্মস্থানৰ এপ্সমূহ <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"আপোনাৰ ব্যক্তিগত এপ্সমূহ <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"এই ডিভাইচটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>এ প্ৰদান কৰিছে"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইচৰ পৰিচালনা"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"ভিপিএন"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰা হৈছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"আপোনাৰ প্ৰশাসকে নেটৱৰ্ক লগিং অন কৰিছে, যিয়ে আপোনাৰ ডিভাইচটোত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰে।"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"আপোনাৰ প্ৰশাসকে নেটৱৰ্ক লগিং অন কৰিছে, যিয়ে আপোনাৰ কৰ্মস্থানৰ প্ৰ’ফাইলত ট্ৰেফিক নিৰীক্ষণ কৰে কিন্তু আপোনাৰ ব্যক্তিগত প্ৰ’ফাইলত নকৰে।"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"এই ডিভাইচটো <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে। ইমেইল আৰু ব্ৰাউজিঙৰ ডেটাকে ধৰি আপোনাৰ নেটৱৰ্ক সম্পৰ্কীয় কাৰ্যকলাপ আপোনাৰ আইটি প্ৰশাসকে দেখা পায়।"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"এই ডিভাইচটো <xliff:g id="VPN_APP_0">%1$s</xliff:g> আৰু <xliff:g id="VPN_APP_1">%2$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে। ইমেইল আৰু ব্ৰাউজিঙৰ ডেটাকে ধৰি আপোনাৰ নেটৱৰ্ক সম্পৰ্কীয় কাৰ্যকলাপ আপোনাৰ আইটি প্ৰশাসকে দেখা পায়।"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"আপোনাৰ কৰ্মস্থানৰ এপ্সমূহ <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে। ইমেইল আৰু ব্ৰাউজিঙৰ ডেটাকে ধৰি আপুনি কৰ্মস্থানৰ এপ্সমূহত কৰা নেটৱৰ্ক সম্পৰ্কীয় কাৰ্যকলাপ আপোনাৰ আইটি প্ৰশাসক আৰু ভিপিএন প্ৰদানকাৰীয়ে দেখা পায়।"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"আপোনাৰ ব্যক্তিগত এপ্সমূহ <xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে ইণ্টাৰনেটৰ সৈতে সংযুক্ত হৈ আছে। ইমেইল আৰু ব্ৰাউজিঙৰ ডেটাকে ধৰি আপোনাৰ নেটৱৰ্ক সম্পৰ্কীয় কাৰ্যকলাপ আপোনাৰ ভিপিএন প্ৰদানকাৰীয়ে দেখা পায়।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ছেটিং খোলক"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে। আপোনাৰ অভিভাৱকে আপুনি ব্যৱহাৰ কৰা এপ্, আপোনাৰ অৱস্থান আৰু আপুনি ডিভাইচত অতিবাহিত কৰা সময়ৰ দৰে তথ্য চাব আৰু পৰিচালনা কৰিব পাৰে।"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"বেটাৰী শেষ হোৱাৰ সম্ভাৱনা থাকিলে অন কৰক"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"নালাগে, ধন্যবাদ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI হীপ ডাম্প কৰক"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"এপ্লিকেশ্বনসমূহে আপোনাৰ <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" আৰু "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"সম্প্ৰচাৰ নাম"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"পাছৱৰ্ড"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ছেভ কৰক"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"আৰম্ভ কৰা হৈছে…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্ৰচাৰ কৰিব নোৱাৰি"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 51bd3ef..d3be51e 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skrinşotu yenidən çəkin"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Skrinşotu yadda saxlamaq mümkün olmadı"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Skrinşot çəkməyə tətbiq və ya təşkilat tərəfindən icazə verilmir"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Redaktə edin"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinşota düzəliş edin"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Skrinşotu paylaşın"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Təşkilatınız bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən təmin edilib"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Bu cihaz təşkilatınıza məxsusdur və <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur və <xliff:g id="VPN_APP">%2$s</xliff:g> vasitəsilə internetə qoşulub"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu cihaz təşkilatınıza məxsusdur"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Bu cihaz təşkilatınıza məxsusdur və VPN vasitəsilə internetə qoşulub"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> təşkilatına məxsusdur və VPN vasitəsilə internetə qoşulub"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Təşkilat iş profilində şəbəkə ötürülməsinə nəzarət edə bilər"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> iş profilində şəbəkə ötürülməsinə nəzarət edə bilər"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"İş profili şəbəkəsi fəalliyyətini IT admini görə bilir"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Şəbəkəyə nəzarət edilə bilər"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Bu cihaz VPN vasitəsilə internetə qoşulub"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"İş tətbiqləriniz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Şəxsi tətbiqləriniz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən təmin edilib"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz idarəetməsi"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN (Virtual Şəxsi Şəbəkələr)"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Bu cihazda sertifikat səlahiyyəti quraşdırıldı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Admin cihazda şəbəkə ötürülməsinə nəzarət edən şəbəkə qeydlərini aktiv etdi."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Admininiz şəxsi profilinizdəki deyil, iş profilinizdəki trafikə nəzarət edən şəbəkə qeydiyyatını aktiv edib."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz İT admininiz görünür."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Bu cihaz <xliff:g id="VPN_APP_0">%1$s</xliff:g> və <xliff:g id="VPN_APP_1">%2$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz İT admininiz görünür."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"İş tətbiqləriniz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz İT admininiz və VPN provayderinizə görünür."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Şəxsi tətbiqləriniz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz VPN provayderinizə görünür."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" ("</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ayarlarını açın"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz valideyniniz tərəfindən idarə olunur. Valideyniniz işlətdiyiniz tətbiqlər, məkanınız və ekran vaxtınız kimi bilgiləri görə və idarə edə bilər."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Batareya bitmək üzrə olduqda aktiv edin"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Xeyr, təşəkkür"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Tətbiqlər <xliff:g id="TYPES_LIST">%s</xliff:g> istifadə edir."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" və "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Yayım Adı"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Parol"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saxlayın"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Başlanır…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayımlamaq mümkün deyil"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 04b51eb..502db5e 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probajte da ponovo napravite snimak ekrana"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Čuvanje snimka ekrana nije uspelo"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Delite snimak ekrana"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je vlasnik ovog uređaja i može da nadgleda mrežni saobraćaj"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada organizaciji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet preko VPN-ova"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Vlasnik ovog uređaja je <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, a povezan je na internet preko VPN-ova"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizacija može da prati mrežni saobraćaj na poslovnom profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može da nadgleda mrežni saobraćaj na poslovnom profilu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivnost na mreži poslovnog profila je vidljiva IT administratoru"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadgleda"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ovaj uređaj je povezan na internet preko VPN-ova"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajima"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom uređaju je instaliran autoritet za izdavanje sertifikata. Bezbedni mrežni saobraćaj može da se prati ili menja."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na uređaju."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio evidentiranje mreže, koje prati saobraćaj na poslovnom profilu, ali ne i na ličnom profilu."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ovaj uređaj je povezan na internet preko: <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše poslovne aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži u poslovnim aplikacijama, uključujući imejlove i podatke pregledanja, vidljiva je IT administratoru i dobavljaču VPN-a."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše lične aplikacije su povezane na internet preko: <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući imejlove i podatke pregledanja, vidljiva je dobavljaču VPN-a."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvori podešavanja VPN-a"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja roditelj. Roditelj može da vidi informacije, kao što su aplikacije koje koristiš, tvoju lokaciju i vreme ispred ekrana, i da upravlja njima."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako će baterija verovatno da se isprazni"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
@@ -861,9 +853,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Naziv emitovanja"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Lozinka"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokreće se…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 098bc32..1d320c7 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -78,10 +78,12 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Паспрабуйце зрабіць здымак экрана яшчэ раз"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Не ўдалося захаваць здымак экрана"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Змяніць"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Змяніць здымак экрана"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Абагуліць здымак экрана"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Зняць больш"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Захапіць больш"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Адхіліць здымак экрана"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Перадпрагляд здымка экрана"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Верхняя граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз сеткі VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз сеткі VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ваша арганізацыя можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> можа сачыць за сеткавым трафікам у вашым працоўным профілі"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Дзеянні працоўнага профілю ў сетцы бачныя IT-адміністратару"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"За сеткай могуць сачыць"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Гэта прылада падключана да інтэрнэту праз сеткі VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Вашы працоўныя праграмы падключаны да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Вашы асабістыя праграмы падключаны да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Гэта прылада падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Кіраванне прыладай"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На гэтай прыладзе ўсталяваны цэнтр сертыфікацыі. Ваш абаронены сеткавы трафік могуць праглядваць ці змяняць."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік на вашай прыладзе."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Ваш адміністратар уключыў вядзенне журнала сеткі, з дапамогай якога адсочваецца трафік у вашым працоўным профілі. Трафік вашага асабістага профілю застаецца недаступным."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Гэта прылада падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваш IT-адміністратар можа бачыць вашы дзеянні ў сетцы, у тым ліку інфармацыю пра электронную пошту і даныя прагляду."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Гэта прылада падключана да інтэрнэту праз праграмы \"<xliff:g id="VPN_APP_0">%1$s</xliff:g>\" і \"<xliff:g id="VPN_APP_1">%2$s</xliff:g>\". Ваш IT-адміністратар можа бачыць вашы дзеянні ў сетцы, у тым ліку інфармацыю пра электронную пошту і даныя прагляду."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Вашы працоўныя праграмы падключаны да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваш IT-адміністратар і пастаўшчык VPN могуць бачыць вашы дзеянні ў сетцы ў працоўных праграмах, у тым ліку інфармацыю пра электронную пошту і даныя прагляду."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Вашы асабістыя праграмы падключаны да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Пастаўшчык VPN можа бачыць вашы дзеянні ў сетцы, у тым ліку інфармацыю пра электронную пошту і даныя прагляду."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" ,"</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Адкрыйце налады VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Гэта прылада знаходзіцца пад кантролем бацькоў. Бацькі могуць праглядаць і кантраляваць тваю інфармацыю, напрыклад пра праграмы, якія ты выкарыстоўваеш, даныя пра тваё месцазнаходжанне і час карыстання прыладай."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Уключыце, калі зарад акумулятара заканчваецца"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Не, дзякуй"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Праграмы выкарыстоўваюць: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Назва трансляцыі"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Пароль"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Захаваць"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запускаецца…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не ўдалося запусціць трансляцыю"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c6b8c2e..40d0b14 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Опитайте да направите екранна снимка отново"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Екранната снимка не може да се запази"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Правенето на екранни снимки не е разрешено от приложението или организацията ви"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Редактиране"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Редактиране на екранната снимка"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Споделяне на екранната снимка"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> притежава това устройство и може да наблюдава трафика в мрежата"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Това устройство е предоставено от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Това устройство принадлежи на организацията ви и е свързано с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с интернет чрез <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Това устройство принадлежи на организацията ви"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Това устройство принадлежи на организацията ви и е свързано с интернет чрез няколко VPN."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е свързано с интернет чрез няколко VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Организацията ви може да наблюдава трафика в мрежата в служебния ви потребителски профил"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> може да наблюдава трафика в мрежата в служебния ви потребителски профил"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Мрежовата активност в служебния потребителски профил е видима за системния ви администратор"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мрежата може да се наблюдава"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Това устройство е свързано с интернет чрез няколко VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Служебните ви приложения са свързани с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Личните ви приложения са свързани с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Това устройство е свързано с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Това устройство е предоставено от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление на устройствата"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На това устройство е инсталиран сертифициращ орган. Трафикът в защитената ви мрежа може да бъде наблюдаван или променян."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администраторът ви е включил функцията за регистриране на мрежовата активност, която следи трафика на устройството ви."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администраторът ви е включил функцията за регистриране на мрежовата активност, която следи трафика в служебния ви потребителски профил, но не и в личния."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Това устройство е свързано с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>. Активността ви в мрежата, включително имейлите и данните за сърфирането, е видима за системния ви администратор."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Това устройство е свързано с интернет чрез <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Активността ви в мрежата, включително имейлите и данните за сърфирането, е видима за системния ви администратор."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Служебните ви приложения са свързани с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>. Активността ви в мрежата в тези приложения, включително имейлите и данните за сърфирането, е видима за системния ви администратор и доставчика ви на VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Личните ви приложения са свързани с интернет чрез <xliff:g id="VPN_APP">%1$s</xliff:g>. Активността ви в мрежата, включително имейлите и данните за сърфирането, е видима от доставчика ви на VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Отваряне на настройките за VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Това устройство се управлява от родителя ви. Той може да вижда и управлява информация, като например приложенията, които използвате, местоположението ви и времето на ползване."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Включване, когато е вероятно батерията да се изтощи"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Не, благодаря"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Някои приложения използват <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Име на предаването"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Парола"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Запазване"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Стартира се…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Предаването не е възможно"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index df5df59..a15e9ce 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"আবার স্ক্রিনশট নেওয়ার চেষ্টা করুন"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"স্ক্রিনশট সেভ করা যায়নি"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"এডিট করুন"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্রিনশট এডিট করুন"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্রিনশট শেয়ার করুন"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং এরা ডিভাইসের নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> এই ডিভাইসের মালিক এবং এটির নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> দিয়েছে"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"এই ডিভাইস আপনার প্রতিষ্ঠানের এবং <xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর এবং <xliff:g id="VPN_APP">%2$s</xliff:g>-এর মাধ্যমে ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"এই ডিভাইস আপনার প্রতিষ্ঠানের এবং একাধিক ভিপিএন-এর মাধ্যমে ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-এর এবং একাধিক ভিপিএন-এর মাধ্যমে ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"আপনার প্রতিষ্ঠান আপনার কর্মস্থলের প্রোফাইলের নেটওয়ার্ক ট্রাফিকে নজর রাখতে পারে"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> আপনার কর্মস্থলের প্রোফাইলের নেটওয়ার্ক ট্রাফিকে নজর রাখতে পারে"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"আপনার আইটি অ্যাডমিন অফিস প্রোফাইল নেটওয়ার্ক অ্যাক্টিভিটি দেখতে পারবেন"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"নেটওয়ার্কের উপরে নজর রাখা হতে পারে"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"একাধিক ভিপিএন-এর মাধ্যমে আপনার ডিভাইস ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার অফিসের অ্যাপ ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার ব্যক্তিগত অ্যাপ ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে এই ডিভাইস ইন্টারনেটের সাথে কানেক্ট করা আছে"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"এই ডিভাইস <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> দিয়েছে"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ডিভাইসের পরিচালনা"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইসে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিকের উপরে নজর রাখে।"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"আপনার অ্যাডমিন নেটওয়ার্ক লগ করা চালু করেছেন যা আপনার অফিস প্রোফাইলে ট্রাফিক মনিটর করে তবে ব্যক্তিগত প্রোফাইলে করে না।"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার ডিভাইস ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ নেটওয়ার্ক অ্যাক্টিভিটি আপনার আইটি অ্যাডমিন দেখতে পারবেন।"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ও <xliff:g id="VPN_APP_1">%2$s</xliff:g>-এর মাধ্যমে এই ডিভাইস ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ নেটওয়ার্ক অ্যাক্টিভিটি আপনার আইটি অ্যাডমিন দেখতে পারবেন।"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার অফিসের অ্যাপ ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ অফিসের অ্যাপে করা নেটওয়ার্ক অ্যাক্টিভিটি আপনার আইটি অ্যাডমিন ও ভিপিএন প্রদানকারী দেখতে পারবেন।"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার ব্যক্তিগত অ্যাপ ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ নেটওয়ার্ক অ্যাক্টিভিটি আপনার ভিপিএন প্রদানকারী দেখতে পারবেন।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN সেটিংস খুলুন"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন। আপনার অভিভাবক আপনার ব্যবহার করা অ্যাপ, লোকেশন ও স্ক্রিন টাইমের মতো তথ্যগুলি দেখতে এবং ম্যানেজ করতে পারেন।"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ব্যাটারির চার্জ শেষ হয়ে যাওয়ার সম্ভাবনা দেখা দিলে চালু করুন"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"না থাক"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"অ্যাপ্লিকেশনগুলি আপনার <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যবহার করছে।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" এবং "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ব্রডকাস্টের নাম"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"পাসওয়ার্ড"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"সেভ করুন"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"শুরু করা হচ্ছে…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্রচার করা যাচ্ছে না"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b88e9bf..5eac08a 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -78,10 +78,12 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo snimiti ekran"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nije moguće sačuvati snimak ekrana"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Uredite"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Uredite snimak ekrana"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Dijeljenje snimka ekrana"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimite više"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimi više"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Gornja granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> upravlja ovim uređajem i može nadzirati mrežni saobraćaj"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ovaj uređaj pripada vašoj organizaciji i povezan je na internet putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je na internet putem VPN-ova"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može pratiti mrežni saobraćaj na vašem profilu."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može pratiti mrežni saobraćaj na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Mrežna aktivnost radnog profila je vidljiva vašem IT administratoru"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža može biti nadzirana"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ovaj uređaj je povezan na internet putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše poslovne aplikacije su povezane s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše lične aplikacije su povezane na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ovaj uređaj je povezan na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN mreža"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA certifikat je instaliran na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Vaš administrator je uključio zapisivanje na mreži, čime se prati saobraćaj na vašem uređaju."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio zapisivanje na mreži, čime se nadzire saobraćaj na vašem radnom profilu, ali ne i na ličnom profilu."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ovaj uređaj je povezan na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša mrežna aktivnost, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem IT administratoru."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ovaj uređaj je povezan na internet putem aplikacija <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša mrežna aktivnost, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem IT administratoru."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše poslovne aplikacije su povezane na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša mrežna aktivnost u poslovnim aplikacijama, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem IT administratoru i pružaocu VPN usluga."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše lične aplikacije su povezane na internet putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša mrežna aktivnost, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem pružaocu VPN usluga."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvorite postavke VPN mreže"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja tvoj roditelj. Roditelj može vidjeti i upravljati informacijama kao što su aplikacije koje koristiš, lokacija i vrijeme korištenja uređaja."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Uključite ako je vjerovatno da će se baterija istrošiti"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji SysUI mem."</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
@@ -861,14 +853,16 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Naziv emitiranja"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Lozinka"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Sačuvaj"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokretanje…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nije moguće emitirati"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
<string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
- <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za razgovor"</string>
+ <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti razgovora"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da ga dodate na početni ekran"</string>
<string name="no_conversations_text" msgid="5354115541282395015">"Vaši nedavni razgovori će se pojaviti ovdje"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Prioritetni razgovori"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 727712b..5db8dd9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prova de tornar a fer una captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No es pot desar la captura de pantalla"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edita"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edita la captura de pantalla"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Comparteix la captura de pantalla"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> és propietària d\'aquest dispositiu i és possible que supervisi el trànsit de xarxa"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona aquest dispositiu"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Aquest dispositiu pertany a la teva organització i es connecta a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i es connecta a Internet a través de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Aquest dispositiu pertany a la teva organització"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Aquest dispositiu pertany a la teva organització i es connecta a Internet a través de VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i es connecta a Internet a través de VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"És possible que la teva organització supervisi el trànsit de xarxa al teu perfil de treball"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"És possible que <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> supervisi el trànsit de xarxa del teu perfil de treball"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"L\'administrador de TI pot veure l\'activitat de la xarxa del perfil de treball"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"És possible que la xarxa estigui supervisada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Aquest dispositiu es connecta a Internet a través de VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Les aplicacions de treball es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Les aplicacions personals es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona aquest dispositiu"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestió del dispositiu"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"S\'ha instal·lat una autoritat de certificació en aquest dispositiu. És possible que el trànsit de xarxa segura se supervisi o es modifiqui."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"L\'administrador ha activat el registre de xarxa, que supervisa el trànsit del teu dispositiu."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"L\'administrador ha activat el registre de xarxa, que monitora el trànsit al teu perfil de treball, però no al personal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu administrador de TI pot veure l\'activitat de la teva xarxa, inclosos els correus electrònics i les dades de navegació."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Aquest dispositiu es connecta a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. El teu administrador de TI pot veure l\'activitat de la teva xarxa, inclosos els correus electrònics i les dades de navegació."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Les aplicacions de treball es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu administrador de TI i el teu proveïdor de VPN poden veure l\'activitat de la teva xarxa en aplicacions de treball, inclosos els correus electrònics i les dades de navegació."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Les aplicacions personals es connecten a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. El teu proveïdor de VPN pot veure l\'activitat de la teva xarxa, inclosos els correus electrònics i les dades de navegació."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Obre la configuració de la VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"El teu pare o mare gestionen aquest dispositiu, i poden veure i gestionar informació com ara les aplicacions que utilitzes, la teva ubicació i el teu temps de connexió."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Activa\'l quan sigui probable que et quedis sense bateria"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, gràcies"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Aboca el monticle de SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nom de l\'emissió"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Contrasenya"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Desa"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"S\'està iniciant…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No es pot emetre"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e61e3b5..4b865a4 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zkuste snímek pořídit znovu"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Snímek obrazovky se nepodařilo uložit"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Upravit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Upravit snímek obrazovky"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Sdílet snímek obrazovky"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Toto zařízení spravuje organizace <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, která může sledovat síťový provoz"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zařízení poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zařízení patří vaší organizaci"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zařízení patří vaší organizaci a je připojeno k internetu prostřednictvím sítí VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a je připojeno k internetu prostřednictvím sítí VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizace může ve vašem pracovním profilu sledovat síťový provoz"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> může ve vašem pracovním profilu sledovat síťový provoz"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivitu pracovního profilu na síti vidí administrátor IT"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Síť může být sledována"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Toto zařízení je připojeno k internetu prostřednictvím sítí VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše pracovní aplikace jsou připojeny k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše osobní aplikace jsou připojeny k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Toto zařízení je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Toto zařízení poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zařízení"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V zařízení je nainstalována certifikační autorita. Zabezpečený síťový provoz může být sledován nebo upravován."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrátor zapnul protokolování sítě, které monitoruje síťový provoz v zařízení."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrátor zapnul protokolování sítě, které monitoruje síťový provoz ve vašem pracovním profilu (ale ne v osobním)."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Toto zařízení je připojeno k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaší síťovou aktivitu (jako jsou e-maily a údaje o prohlížení) vidí administrátor IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Toto zařízení je připojeno k internetu prostřednictvím aplikací <xliff:g id="VPN_APP_0">%1$s</xliff:g> a <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaší síťovou aktivitu (jako jsou e-maily a údaje o prohlížení) vidí administrátor IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše pracovní aplikace jsou připojeny k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaší síťovou aktivitu v pracovních aplikacích (jako jsou e-maily a údaje o prohlížení) vidí administrátor IT a poskytovatel VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše osobní aplikace jsou připojeny k internetu prostřednictvím aplikace <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaší síťovou aktivitu (jako jsou e-maily a údaje o prohlížení) vidí poskytovatel VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otevřít nastavení VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zařízení spravuje rodič. Rodič může zobrazit údaje, jako jsou používané aplikace, tvá poloha a čas strávený na zařízení."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Zapnout, když bude pravděpodobné, že se vybije baterie"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, díky"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Výpis haldy SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikace využívají tato oprávnění: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Název vysílání"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Heslo"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Uložit"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Spouštění…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Vysílání se nezdařilo"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
@@ -898,7 +892,7 @@
<string name="audio_status" msgid="4237055636967709208">"Poslouchá"</string>
<string name="game_status" msgid="1340694320630973259">"Hraji hru"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Přátelé"</string>
- <string name="empty_status" msgid="5938893404951307749">"Pojďme chatovat."</string>
+ <string name="empty_status" msgid="5938893404951307749">"Pojďme chatovat!"</string>
<string name="status_before_loading" msgid="1500477307859631381">"Obsah se brzy zobrazí"</string>
<string name="missed_call" msgid="4228016077700161689">"Zmeškaný hovor"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 62fccd0..2af84d9 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -33,128 +33,128 @@
<!-- no translation found for tile_states_default:2 (9192445505551219506) -->
<string-array name="tile_states_internet">
<item msgid="5499482407653291407">"Nedostupné"</item>
- <item msgid="3048856902433862868">"Vyp"</item>
- <item msgid="6877982264300789870">"Zap"</item>
+ <item msgid="3048856902433862868">"Vypnuto"</item>
+ <item msgid="6877982264300789870">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_wifi">
<item msgid="8054147400538405410">"Nedostupné"</item>
- <item msgid="4293012229142257455">"Vyp"</item>
- <item msgid="6221288736127914861">"Zap"</item>
+ <item msgid="4293012229142257455">"Vypnuto"</item>
+ <item msgid="6221288736127914861">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_cell">
<item msgid="1235899788959500719">"Nedostupné"</item>
- <item msgid="2074416252859094119">"Vyp"</item>
- <item msgid="287997784730044767">"Zap"</item>
+ <item msgid="2074416252859094119">"Vypnuto"</item>
+ <item msgid="287997784730044767">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_battery">
<item msgid="6311253873330062961">"Nedostupné"</item>
- <item msgid="7838121007534579872">"Vyp"</item>
- <item msgid="1578872232501319194">"Zap"</item>
+ <item msgid="7838121007534579872">"Vypnuto"</item>
+ <item msgid="1578872232501319194">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_dnd">
<item msgid="467587075903158357">"Nedostupné"</item>
- <item msgid="5376619709702103243">"Vyp"</item>
- <item msgid="4875147066469902392">"Zap"</item>
+ <item msgid="5376619709702103243">"Vypnuto"</item>
+ <item msgid="4875147066469902392">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_flashlight">
<item msgid="3465257127433353857">"Nedostupné"</item>
- <item msgid="5044688398303285224">"Vyp"</item>
- <item msgid="8527389108867454098">"Zap"</item>
+ <item msgid="5044688398303285224">"Vypnuto"</item>
+ <item msgid="8527389108867454098">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_rotation">
<item msgid="4578491772376121579">"Nedostupné"</item>
- <item msgid="5776427577477729185">"Vyp"</item>
- <item msgid="7105052717007227415">"Zap"</item>
+ <item msgid="5776427577477729185">"Vypnuto"</item>
+ <item msgid="7105052717007227415">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_bt">
<item msgid="5330252067413512277">"Nedostupné"</item>
- <item msgid="5315121904534729843">"Vyp"</item>
- <item msgid="503679232285959074">"Zap"</item>
+ <item msgid="5315121904534729843">"Vypnuto"</item>
+ <item msgid="503679232285959074">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_airplane">
<item msgid="1985366811411407764">"Nedostupné"</item>
- <item msgid="4801037224991420996">"Vyp"</item>
- <item msgid="1982293347302546665">"Zap"</item>
+ <item msgid="4801037224991420996">"Vypnuto"</item>
+ <item msgid="1982293347302546665">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_location">
<item msgid="3316542218706374405">"Nedostupné"</item>
- <item msgid="4813655083852587017">"Vyp"</item>
- <item msgid="6744077414775180687">"Zap"</item>
+ <item msgid="4813655083852587017">"Vypnuto"</item>
+ <item msgid="6744077414775180687">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_hotspot">
<item msgid="3145597331197351214">"Nedostupné"</item>
- <item msgid="5715725170633593906">"Vyp"</item>
- <item msgid="2075645297847971154">"Zap"</item>
+ <item msgid="5715725170633593906">"Vypnuto"</item>
+ <item msgid="2075645297847971154">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_color_correction">
<item msgid="2840507878437297682">"Nedostupné"</item>
- <item msgid="1909756493418256167">"Vyp"</item>
- <item msgid="4531508423703413340">"Zap"</item>
+ <item msgid="1909756493418256167">"Vypnuto"</item>
+ <item msgid="4531508423703413340">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_inversion">
<item msgid="3638187931191394628">"Nedostupné"</item>
- <item msgid="9103697205127645916">"Vyp"</item>
- <item msgid="8067744885820618230">"Zap"</item>
+ <item msgid="9103697205127645916">"Vypnuto"</item>
+ <item msgid="8067744885820618230">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_saver">
<item msgid="39714521631367660">"Nedostupné"</item>
- <item msgid="6983679487661600728">"Vyp"</item>
- <item msgid="7520663805910678476">"Zap"</item>
+ <item msgid="6983679487661600728">"Vypnuto"</item>
+ <item msgid="7520663805910678476">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_dark">
<item msgid="2762596907080603047">"Nedostupné"</item>
- <item msgid="400477985171353">"Vyp"</item>
- <item msgid="630890598801118771">"Zap"</item>
+ <item msgid="400477985171353">"Vypnuto"</item>
+ <item msgid="630890598801118771">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_work">
<item msgid="389523503690414094">"Nedostupné"</item>
- <item msgid="8045580926543311193">"Vyp"</item>
- <item msgid="4913460972266982499">"Zap"</item>
+ <item msgid="8045580926543311193">"Vypnuto"</item>
+ <item msgid="4913460972266982499">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_cast">
<item msgid="6032026038702435350">"Nedostupné"</item>
- <item msgid="1488620600954313499">"Vyp"</item>
- <item msgid="588467578853244035">"Zap"</item>
+ <item msgid="1488620600954313499">"Vypnuto"</item>
+ <item msgid="588467578853244035">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_night">
<item msgid="7857498964264855466">"Nedostupné"</item>
- <item msgid="2744885441164350155">"Vyp"</item>
- <item msgid="151121227514952197">"Zap"</item>
+ <item msgid="2744885441164350155">"Vypnuto"</item>
+ <item msgid="151121227514952197">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_screenrecord">
<item msgid="1085836626613341403">"Nedostupné"</item>
- <item msgid="8259411607272330225">"Vyp"</item>
- <item msgid="578444932039713369">"Zap"</item>
+ <item msgid="8259411607272330225">"Vypnuto"</item>
+ <item msgid="578444932039713369">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_reverse">
<item msgid="3574611556622963971">"Nedostupné"</item>
- <item msgid="8707481475312432575">"Vyp"</item>
- <item msgid="8031106212477483874">"Zap"</item>
+ <item msgid="8707481475312432575">"Vypnuto"</item>
+ <item msgid="8031106212477483874">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_reduce_brightness">
<item msgid="1839836132729571766">"Nedostupné"</item>
- <item msgid="4572245614982283078">"Vyp"</item>
- <item msgid="6536448410252185664">"Zap"</item>
+ <item msgid="4572245614982283078">"Vypnuto"</item>
+ <item msgid="6536448410252185664">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_cameratoggle">
<item msgid="6680671247180519913">"Nedostupné"</item>
- <item msgid="4765607635752003190">"Vyp"</item>
- <item msgid="1697460731949649844">"Zap"</item>
+ <item msgid="4765607635752003190">"Vypnuto"</item>
+ <item msgid="1697460731949649844">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_mictoggle">
<item msgid="6895831614067195493">"Nedostupné"</item>
- <item msgid="3296179158646568218">"Vyp"</item>
- <item msgid="8998632451221157987">"Zap"</item>
+ <item msgid="3296179158646568218">"Vypnuto"</item>
+ <item msgid="8998632451221157987">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_controls">
<item msgid="8199009425335668294">"Nedostupné"</item>
- <item msgid="4544919905196727508">"Vyp"</item>
- <item msgid="3422023746567004609">"Zap"</item>
+ <item msgid="4544919905196727508">"Vypnuto"</item>
+ <item msgid="3422023746567004609">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_wallet">
<item msgid="4177615438710836341">"Nedostupné"</item>
- <item msgid="7571394439974244289">"Vyp"</item>
- <item msgid="6866424167599381915">"Zap"</item>
+ <item msgid="7571394439974244289">"Vypnuto"</item>
+ <item msgid="6866424167599381915">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_qr_code_scanner">
<item msgid="7435143266149257618">"Nedostupné"</item>
@@ -163,8 +163,8 @@
</string-array>
<string-array name="tile_states_alarm">
<item msgid="4936533380177298776">"Nedostupné"</item>
- <item msgid="2710157085538036590">"Vyp"</item>
- <item msgid="7809470840976856149">"Zap"</item>
+ <item msgid="2710157085538036590">"Vypnuto"</item>
+ <item msgid="7809470840976856149">"Zapnuto"</item>
</string-array>
<string-array name="tile_states_onehanded">
<item msgid="8189342855739930015">"Nedostupné"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index dcaebc7..41e27dd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv at tage et screenshot igen"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Dit screenshot kunne ikke gemmes."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller din organisation tillader ikke, at du tager screenshots"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Del screenshottet"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enhed tilhører din organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Denne enhed tilhører din organisation, og den har forbindelse til nettet via VPN-forbindelser"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, og den har forbindelse til nettet via VPN-forbindelser"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Din organisation kan overvåge netværkstrafikken på din arbejdsprofil"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan overvåge netværkstrafik på din arbejdsprofil"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Din it-administrator kan se netværksaktivitet på din arbejdsprofil"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netværket kan være overvåget"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Denne enhed har forbindelse til nettet via VPN-forbindelser"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Dine arbejdsapps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Dine personlige apps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Denne enhed har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Denne enhed er leveret af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administration af enheder"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Der er installeret et nøglecenter på denne enhed. Din sikre netværkstrafik kan overvåges eller ændres."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Din administrator har aktiveret netværksregistrering, som overvåger trafik på din enhed."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Din administrator har aktiveret netværkslogging, som overvåger trafik på din arbejdsprofil, men ikke på din personlige profil."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Denne enhed har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Denne enhed har forbindelse til nettet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din it-administrator."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Dine arbejdsapps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet i arbejdsapps, herunder mails og browserdata, er synlig for din it-administrator og VPN-udbyder."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Dine personlige apps har forbindelse til nettet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din netværksaktivitet, herunder mails og browserdata, er synlig for din VPN-udbyder."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Åbn VPN-indstillinger"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Denne enhed administreres af din forælder. Din forælder kan se og administrere oplysninger såsom de apps, du bruger, din lokation og din skærmtid."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktivér, når det ser ud til, at batteriet løber tør"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nej tak"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Gem SysUI-heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps anvender enhedens <xliff:g id="TYPES_LIST">%s</xliff:g>"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Navn på udsendelse"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Adgangskode"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gem"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starter…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Der kan ikke udsendes en fællesbesked"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 962be16..0ee1363 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Versuche noch einmal, den Screenshot zu erstellen"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Screenshot kann nicht gespeichert werden"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Die App oder deine Organisation lässt das Erstellen von Screenshots nicht zu"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Bearbeiten"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bearbeiten"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot teilen"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ist der Eigentümer dieses Geräts und kann den Netzwerkverkehr überwachen"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> zur Verfügung gestellt"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Dieses Gerät gehört deiner Organisation und ist über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> und ist über <xliff:g id="VPN_APP">%2$s</xliff:g> mit dem Internet verbunden"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dieses Gerät gehört deiner Organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Dieses Gerät gehört deiner Organisation und ist über VPNs mit dem Internet verbunden"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> und ist über VPNs mit dem Internet verbunden"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Deine Organisation kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kann den Netzwerkverkehr in deinem Arbeitsprofil überwachen"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Dein IT-Administrator kann die Netzwerkaktivitäten deines Arbeitsprofils sehen"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Das Netzwerk wird eventuell überwacht"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Dieses Gerät ist über VPNs mit dem Internet verbunden"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Deine geschäftlichen Apps sind über „<xliff:g id="VPN_APP">%1$s</xliff:g>“ mit dem Internet verbunden"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Deine privaten Apps sind über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Dieses Gerät ist über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> zur Verfügung gestellt"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Geräteverwaltung"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Auf dem Gerät ist das Zertifikat einer Zertifizierungsstelle installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit wird der Netzwerkverkehr auf deinem Gerät überwacht."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit werden die Zugriffe in deinem Arbeitsprofil erfasst, jedoch nicht in deinem privaten Profil."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Dieses Gerät ist über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator sichtbar."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Dieses Gerät ist über <xliff:g id="VPN_APP_0">%1$s</xliff:g> und <xliff:g id="VPN_APP_1">%2$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator sichtbar."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Deine geschäftlichen Apps sind über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten in geschäftlichen Apps, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator und deinen VPN-Anbieter sichtbar."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Deine privaten Apps sind über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für deinen VPN-Anbieter sichtbar."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN-Einstellungen öffnen"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dieses Gerät wird von deinen Eltern verwaltet. Sie können unter anderem Informationen über deine genutzten Apps, deinen Standort und deine Gerätenutzungsdauer einsehen und verwalten."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktivieren, wenn der Akku wahrscheinlich nicht mehr lange hält"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nein danke"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" und "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Name für Nachricht an alle"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Passwort"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Speichern"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Wird gestartet…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Übertragung nicht möglich"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 43e124e..4676f2b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Δοκιμάστε να κάνετε ξανά λήψη του στιγμιότυπου οθόνης"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Δεν είναι δυνατή η αποθήκευση στιγμιότυπου οθόνης."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Η λήψη στιγμιότυπων οθόνης δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Επεξεργασία"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Επεξεργασία στιγμιότυπου οθόνης"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Κοινοποίηση στιγμιότυπου οθόνης"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Αυτή η συσκευή ανήκει στον οργανισμό σας και συνδέεται στο διαδίκτυο μέσω VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> και συνδέεται στο διαδίκτυο μέσω VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ο οργανισμός σας μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου στο προφίλ εργασίας σας"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου στο προφίλ εργασίας σας"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Η δραστηριότητα δικτύου του προφίλ εργασίας είναι ορατή στον διαχειριστή IT σας"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Αυτή η συσκευή συνδέεται στο διαδίκτυο μέσω VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Οι εφαρμογές εργασιών σας συνδέονται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Οι προσωπικές σας εφαρμογές συνδέονται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Αυτή η συσκευή συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Αυτή η συσκευή παρέχεται από τον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Διαχείριση συσκευών"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Μια αρχή έκδοσης πιστοποιητικών έχει εγκατασταθεί σε αυτήν τη συσκευή. Η ασφαλής επισκεψιμότητα δικτύου σας μπορεί να παρακολουθείται ή να τροποποιείται."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Ο διαχειριστής σας ενεργοποίησε την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στη συσκευή σας."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Ο διαχειριστής σας έχει ενεργοποιήσει την καταγραφή δικτύου, η οποία παρακολουθεί την επισκεψιμότητα στο προφίλ εργασίας σας, αλλά όχι στο προσωπικό προφίλ σας."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Αυτή η συσκευή συνδέεται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>. Η δραστηριότητα δικτύου σας, συμπεριλαμβανομένων των μηνυμάτων ηλεκτρονικού ταχυδρομείου και των δεδομένων περιήγησης, είναι ορατή στον διαχειριστή IT σας."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Αυτή η συσκευή συνδέεται στο διαδίκτυο μέσω των εφαρμογών <xliff:g id="VPN_APP_0">%1$s</xliff:g> και <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Η δραστηριότητα δικτύου σας, συμπεριλαμβανομένων των μηνυμάτων ηλεκτρονικού ταχυδρομείου και των δεδομένων περιήγησης, είναι ορατή στον διαχειριστή IT σας."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Οι εφαρμογές εργασιών σας συνδέονται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>. Η δραστηριότητα δικτύου σας στις εφαρμογές εργασίας, συμπεριλαμβανομένων των μηνυμάτων ηλεκτρονικού ταχυδρομείου και των δεδομένων περιήγησης, είναι ορατή στον διαχειριστή IT και τον πάροχο VPN σας."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Οι προσωπικές εφαρμογές σας συνδέονται στο διαδίκτυο μέσω της εφαρμογής <xliff:g id="VPN_APP">%1$s</xliff:g>. Η δραστηριότητα δικτύου, συμπεριλαμβανομένων των μηνυμάτων ηλεκτρονικού ταχυδρομείου και των δεδομένων περιήγησης, είναι ορατή στον πάροχο VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Άνοιγμα Ρυθμίσεων VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου. Ο γονέας σου μπορεί να βλέπει και να διαχειρίζεται πληροφορίες όπως οι εφαρμογές που χρησιμοποιείς, η τοποθεσία σου και ο χρόνος χρήσης."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ενεργοποίηση όταν υπάρχει σημαντική πιθανότητα εξάντλησης της μπαταρίας"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Όχι, ευχαριστώ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Στιγμ. μνήμης SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Οι εφαρμογές χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" και "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Όνομα μετάδοσης"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Κωδικός πρόσβασης"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Αποθήκευση"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Εκκίνηση…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Δεν είναι δυνατή η μετάδοση"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 68375c1..fe02025 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"This device belongs to your organisation and is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"This device belongs to your organisation and is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Work profile network activity is visible to your IT admin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Your admin has turned on network logging, which monitors traffic on your device."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the Internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by trust agent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Sound settings"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically subtitle media"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically caption media"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Close captions tip"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Captions overlay"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"enable"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 2b20555..7c8ce36 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"This device belongs to your organisation and is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"This device belongs to your organisation and is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Work profile network activity is visible to your IT admin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Your admin has turned on network logging, which monitors traffic on your device."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the Internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by trust agent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Sound settings"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically subtitle media"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically caption media"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Close captions tip"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Captions overlay"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"enable"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 68375c1..fe02025 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"This device belongs to your organisation and is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"This device belongs to your organisation and is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Work profile network activity is visible to your IT admin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Your admin has turned on network logging, which monitors traffic on your device."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the Internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by trust agent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Sound settings"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically subtitle media"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically caption media"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Close captions tip"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Captions overlay"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"enable"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 68375c1..fe02025 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> owns this device and may monitor network traffic"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"This device belongs to your organisation and is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"This device belongs to your organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"This device belongs to your organisation and is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> and is connected to the Internet through VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Your organisation may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> may monitor network traffic in your work profile"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Work profile network activity is visible to your IT admin"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Network may be monitored"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"This device is connected to the Internet through VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"This device is provided by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Device management"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"A certificate authority is installed on this device. Your secure network traffic may be monitored or modified."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Your admin has turned on network logging, which monitors traffic on your device."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Your admin has turned on network logging, which monitors traffic in your work profile but not in your personal profile."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"This device is connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"This device is connected to the Internet through <xliff:g id="VPN_APP_0">%1$s</xliff:g> and <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your IT admin."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Your work apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity in work apps, including emails and browsing data, is visible to your IT admin and VPN provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Your personal apps are connected to the Internet through <xliff:g id="VPN_APP">%1$s</xliff:g>. Your network activity, including emails and browsing data, is visible to your VPN provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Open VPN settings"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"This device is managed by your parent. Your parent can see and manage information such as the apps that you use, your location and your screen time."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Kept unlocked by trust agent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Sound settings"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically subtitle media"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatically caption media"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Close captions tip"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Captions overlay"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"enable"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 3e774d9..6415987 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Can\'t save screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Taking screenshots isn\'t allowed by the app or your organization"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
@@ -718,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Turn on when battery is likely to run out"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No thanks"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
@@ -845,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Save"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starting…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
<string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 276f189..d2641d8 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a hacer una captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No se pudo guardar la captura de pantalla"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La app o tu organización no permiten las capturas de pantalla"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> es la organización propietaria de este dispositivo y podría controlar el tráfico de red"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertenece a tu organización y está conectado a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a Internet mediante <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertenece a tu organización y está conectado a Internet mediante una VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a Internet mediante una VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tu organización puede controlar el tráfico de red en tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Es posible que <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> controle el tráfico de red en tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"El administrador de TI puede ver la actividad de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Es posible que la red esté supervisada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado a Internet mediante una VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Tus apps de trabajo están conectadas a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Tus apps personales están conectadas a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración del dispositivo"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Hay una autoridad de certificación instalada en este dispositivo. Es posible que se controle o modifique el tráfico de tu red segura."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Tu administrador activó el registro de red, que supervisa el tráfico en tu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"El administrador activó el registro de red, que supervisa el tráfico de tu perfil de trabajo, pero no el de tu perfil personal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>. El administrador de TI puede ver tu actividad de red (incluidos tus correos electrónicos y datos de navegación)."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet mediante <xliff:g id="VPN_APP_0">%1$s</xliff:g> y <xliff:g id="VPN_APP_1">%2$s</xliff:g>. El administrador de TI puede ver tu actividad de red (incluidos tus correos electrónicos y datos de navegación)."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Tus apps de trabajo están conectadas a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>. El administrador de TI y el proveedor de VPN pueden ver tu actividad de red en las apps de trabajo (incluidos los correos electrónicos y los datos de navegación)."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Tus apps personales están conectadas a Internet mediante <xliff:g id="VPN_APP">%1$s</xliff:g>. El proveedor de VPN puede ver tu actividad (incluidos los correos electrónicos y los datos de navegación)."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configuración de VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre administra este dispositivo. Esa persona puede ver y administrar información, como las apps que usas, tu ubicación y el tiempo de uso."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Actívalo cuando la batería se esté por acabar"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, gracias"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar pila de SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nombre de transmisión"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Contraseña"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Error al iniciar transmisión"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2abbcde..a7be3aa 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Vuelve a intentar hacer la captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"No se puede guardar la captura de pantalla"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"La aplicación o tu organización no permiten realizar capturas de pantalla"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"El dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, que puede monitorizar su tráfico de red"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo lo proporciona <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertenece a tu organización y está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a Internet a través de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertenece a tu organización"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertenece a tu organización y está conectado a Internet a través de varias VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a Internet a través de varias VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tu organización puede supervisar el tráfico de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> puede supervisar el tráfico de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Tu administrador de TI puede ver la actividad de red del perfil de trabajo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Puede que la red esté supervisada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado a Internet a través de varias VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Tus aplicaciones de trabajo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Tus aplicaciones personales están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo lo proporciona <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Administración de dispositivos"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Se ha instalado una entidad de certificación en este dispositivo. Es posible que se supervise o se modifique tu tráfico de red seguro."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"El administrador ha activado el registro de la red para supervisar el tráfico en tu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Tu administrador ha activado el registro de la red, por lo que se monitorizará el tráfico de tu perfil de trabajo, aunque no el de tu perfil personal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> y <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Tu actividad de red, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Tus aplicaciones de trabajo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red en estas aplicaciones, incluidos los correos electrónicos y los datos de navegación, es visible para tu administrador de TI y tu proveedor de VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Tus aplicaciones personales están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. Tu actividad de red, incluidos los correos electrónicos y los datos de navegación, es visible para tu proveedor de VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir ajustes de VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre gestionan este dispositivo y pueden ver y controlar cierta información, como las aplicaciones que utilizas, tu ubicación y tu tiempo de pantalla."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Activar cuando sea probable que se quede sin batería"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No, gracias"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Volcar montículo de SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nombre de emisión"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Contraseña"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No se puede emitir"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c66ca8f..180c1d4 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -78,10 +78,12 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Proovige ekraanipilt uuesti jäädvustada"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekraanipilti ei saa salvestada"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Muutmine"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Ekraanipildi muutmine"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Jaga ekraanipilti"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Jäädvustage rohkem"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Jäädvusta rohkem"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekraanipildist loobumine"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Ekraanipildi eelvaade"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Ülapiir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> on selle seadme omanik ja võib jälgida võrguliiklust"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Selle seadme on andnud <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"See seade kuulub teie organisatsioonile ja on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja on internetiga rakenduse <xliff:g id="VPN_APP">%2$s</xliff:g> kaudu ühendatud"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"See seade kuulub teie organisatsioonile"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Selle seadme omanik on <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"See seade kuulub teie organisatsioonile ja on internetiga VPN-ide kaudu ühendatud"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"See seade kuulub organisatsioonile <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ja on internetiga VPN-ide kaudu ühendatud"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Teie organisatsioon võib jälgida teie tööprofiilil võrguliiklust"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> võib jälgida võrguliiklust teie tööprofiilil"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Tööprofiili võrgutegevused on teie IT-administraatorile nähtavad"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Võrku võidakse jälgida"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"See seade on internetiga VPN-ide kaudu ühendatud"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Teie töörakendused on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Teie isiklikud rakendused on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"See seade on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Selle seadme on andnud <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Seadmehaldus"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sertifikaadi volitus on sellesse seadmesse installitud. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Teie administraator lülitas sisse võrgu logimise funktsiooni, mis jälgib teie seadmes liiklust."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Teie administraator on sisse lülitanud võrgu logimise funktsiooni, mis jälgib liiklust teie võrguprofiilil, kuid mitte teie isiklikul profiilil."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"See seade on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud. Teie võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie IT-administraatorile."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"See seade on internetiga rakenduse <xliff:g id="VPN_APP_0">%1$s</xliff:g> ja <xliff:g id="VPN_APP_1">%2$s</xliff:g> kaudu ühendatud. Teie võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie IT-administraatorile."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Teie töörakendused on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud. Teie töörakenduste võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie IT-administraatorile ning VPN-i teenusepakkujale."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Teie isiklikud rakendused on internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu ühendatud. Teie võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie VPN-i teenusepakkujale."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN-i seadete avamine"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Seda seadet haldab sinu vanem. Sinu vanem näeb ja saab hallata teavet, näiteks kasutatavaid rakendusi, sinu asukohta ja ekraaniaega."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Lülitatakse sisse, kui aku hakkab tühjaks saama"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Tänan, ei"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Rakendused kasutavad järgmisi: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Ülekande nimi"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Parool"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvesta"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Alustamine …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei saa üle kanda"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d35bd8e..1a0483b 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Saiatu berriro pantaila-argazkia ateratzen"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ezin da gorde pantaila-argazkia"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editatu"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editatu pantaila-argazkia"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Partekatu pantaila-argazkia"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da, eta baliteke sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak eman du gailu hau"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Gailua erakundearena da eta <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Gailua <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da eta <xliff:g id="VPN_APP">%2$s</xliff:g> bidez dago konektatuta Internetera"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Gailu hau zure erakundearena da"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Gailua erakundearena da eta VPNen bidez dago konektatuta Internetera"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Gailua <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundearena da eta VPNen bidez dago konektatuta Internetera"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Baliteke erakundeak laneko profileko sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Baliteke <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> erakundeak laneko profilaren sareko trafikoa gainbegiratzea"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IKT saileko administratzaileak laneko profilaren sareko jarduera ikus dezake"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Baliteke sarea gainbegiratuta egotea"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Gailua VPNen bidez dago konektatuta Internetera"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Laneko aplikazioak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Aplikazio pertsonalak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak eman du gailu hau"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gailuaren kudeaketa"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPNa"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure gailuko trafikoa gainbegira dezake."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure laneko profileko trafikoa gainbegira dezake, baina ez zure profil pertsonalekoa."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Gailua <xliff:g id="VPN_APP_0">%1$s</xliff:g> eta <xliff:g id="VPN_APP_1">%2$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Laneko aplikazioak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera. IKT saileko administratzaileak eta VPNaren hornitzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko dituzte."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Aplikazio pertsonalak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera. IKT saileko administratzaileak sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ireki VPN ezarpenak"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Zure gurasoak kudeatzen du gailua. Zure gurasoak gailuko informazioa ikusi eta kudea dezake; besteak beste, zer aplikazio erabiltzen dituzun, zure kokapena zein den eta pantaila aurrean zenbat eta noiz egoten zaren."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktibatu aurrezlea bateria agortzeko arriskua dagoenean"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ez, eskerrik asko"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" eta "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Iragarpenaren izena"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Pasahitza"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gorde"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Abiarazten…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ezin da iragarri"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ea2fb8b..cafe7dc 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -35,12 +35,12 @@
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> اجازه داده شود؟"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"به <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه میدهید به <xliff:g id="USB_DEVICE">%2$s</xliff:g>دسترسی داشته باشد؟\nمجوز ضبط به این برنامه داده نشده است اما میتواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
<string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"به <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> داده شود؟"</string>
- <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g> باز شود؟"</string>
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
<string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"اجازه ضبط به این برنامه داده نشده است اما میتواند صدا را ازطریق این دستگاه USB ضبط کند. استفاده از <xliff:g id="APPLICATION">%1$s</xliff:g> با این دستگاه میتواند مانع از شنیدن تماسها، اعلانها، و زنگهای ساعت شود."</string>
<string name="usb_audio_device_prompt" msgid="7944987408206252949">"استفاده از <xliff:g id="APPLICATION">%1$s</xliff:g> با این دستگاه میتواند مانع از شنیدن تماسها، اعلانها، و زنگهای ساعت شود."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> اجازه داده شود؟"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
- <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> برای رسیدگی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> باز شود؟\nمجوز ضبط به این برنامه داده نشده است اما میتواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
+ <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟\nمجوز ضبط به این برنامه داده نشده است اما میتواند صدا را ازطریق این دستگاه USB ضبط کند."</string>
<string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"برای استفاده از <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
<string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"هیچ برنامه نصب شدهای با این وسیله جانبی USB کار نمیکند. در <xliff:g id="URL">%1$s</xliff:g> دربارهٔ این وسیله جانبی اطلاعات بیشتری کسب کنید"</string>
<string name="title_usb_accessory" msgid="1236358027511638648">"لوازم جانبی USB"</string>
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"دوباره نماگرفت بگیرید"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"نماگرفت ذخیره نمیشود"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"برنامه یا سازمان شما اجازه نمیدهند نماگرفت بگیرید."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ویرایش"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ویرایش نماگرفت"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"همرسانی نماگرفت"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"مالک این دستگاه <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ممکن است ترافیک شبکه را پایش کند"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"این دستگاه را <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تأمین شده است"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"این دستگاه متعلق به سازمان شما است و ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"این دستگاه متعلق به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ازطریق <xliff:g id="VPN_APP">%2$s</xliff:g> به اینترنت متصل شده است"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"این دستگاه به سازمان شما تعلق دارد"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> تعلق دارد"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"این دستگاه متعلق به سازمان شما است و ازطریق چند VPN به اینترنت متصل شده است"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"این دستگاه متعلق به <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> است و ازطریق چند VPN به اینترنت متصل شده است"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ممکن است سازمان شما ترافیک شبکه را در نمایه کاریتان پایش کند"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ممکن است ترافیک شبکه را در نمایه کاری شما پایش کند"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"سرپرست سیستم میتواند فعالیت شبکه نمایه کاری را ببیند"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ممکن است شبکه پایش شود"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"این دستگاه ازطریق چند VPN به اینترنت متصل شده است"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"برنامههای کاریتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"برنامههای شخصیتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"این دستگاه ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"این دستگاه را <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تأمین کرده است"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"مدیریت دستگاه"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"مرجع گواهینامهای در این دستگاه نصب شده است. ممکن است ترافیک امن شبکه شما پایش یا تغییر داده شود."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"سرپرست سیستم شما گزارشگیری از شبکه را (که ترافیک دستگاه شما را پایش میکند) روشن کرده است."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"سرپرست شما گزارشگیری شبکه را که بر ترافیک نمایه کاریتان نظارت میکند، اما بر ترافیک نمایه شخصیتان نظارت نمیکند روشن کرده است."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"این دستگاه ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. سرپرست سیستم شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"این دستگاه ازطریق <xliff:g id="VPN_APP_0">%1$s</xliff:g> و <xliff:g id="VPN_APP_1">%2$s</xliff:g> به اینترنت متصل شده است. سرپرست سیستم شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"برنامههای کاریتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. ارائهدهنده VPN و سرپرست سیستم شما میتوانند فعالیت شبکه شما در برنامههای کاری را (ازجمله ایمیلها و دادههای مرور) ببینند."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"برنامههای شخصیتان ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g> به اینترنت متصل شده است. ارائهدهنده VPN شما میتواند فعالیت شبکه شما را (ازجمله ایمیلها و دادههای مرور) ببیند."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"باز کردن تنظیمات VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"این دستگاه را ولیتان مدیریت میکند. ولیتان میتواند اطلاعاتی مثل برنامههایی که استفاده میکنید، مکانتان، و مدت تماشای صفحهتان را ببیند و مدیریت کند."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"وقتی باتری روبهاتمام است، بهینهسازی باتری را روشن کنید"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"نه متشکرم"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"برنامهها از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده میکنند."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"نام همهفرستی"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"گذرواژه"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ذخیره کردن"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"درحال شروع…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"همهفرستی انجام نشد"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریدهدان کپی شد."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 698031f..cb739d4 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Yritä ottaa kuvakaappaus uudelleen."</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kuvakaappausta ei voi tallentaa"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Sovellus tai organisaatio ei salli kuvakaappauksien tallentamista."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Muuta"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Muokkaa kuvakaappausta"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Jaa kuvakaappaus"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Tämän laitteen tarjoaa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Organisaatiosi omistaa tämän laitteen, joka on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen, joka on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Organisaatiosi omistaa tämän laitteen"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Organisaatiosi omistaa tämän laitteen, joka on yhdistetty internetiin VPN:n kautta"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> omistaa tämän laitteen, joka on yhdistetty internetiin VPN:n kautta"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisaatiosi voi valvoa työprofiilisi verkkoliikennettä."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> voi valvoa työprofiilisi verkkoliikennettä."</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT-järjestelmänvalvoja näkee, mitä työprofiililla tehdään verkossa"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Verkkoa saatetaan valvoa"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Laite on yhdistetty internetiin VPN:n kautta"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Työsovelluksesi on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Henkilökohtaiset sovelluksesi on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Laite on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Tämän laitteen tarjoaa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Laitehallinta"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Laitteeseen on asennettu varmenteen myöntäjä. Suojattua verkkoliikennettäsi voidaan valvoa tai muuttaa."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Järjestelmänvalvoja on ottanut käyttöön verkkolokitietojen tallentamisen, joka valvoo laitteellasi tapahtuvaa liikennettä."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Järjestelmänvalvoja on ottanut käyttöön verkkolokitietojen tallentamisen. Sen avulla seurataan liikennettä työprofiilissasi mutta ei henkilökohtaisessa profiilissasi."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Laite on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>. Verkkotoimintasi, mukaan lukien sähköpostit ja selausdata, näkyy IT-järjestelmänvalvojalle."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Laite on yhdistetty internetiin näiden kautta: <xliff:g id="VPN_APP_0">%1$s</xliff:g> ja <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Verkkotoimintasi, mukaan lukien sähköpostit ja selausdata, näkyy IT-järjestelmänvalvojalle."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Työsovelluksesi on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>. Verkkotoimintasi työsovelluksissa, mukaan lukien sähköpostit ja selausdata, näkyy IT-järjestelmänvalvojalle ja VPN-palveluntarjoajalle."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Henkilökohtaiset sovelluksesi on yhdistetty internetiin tämän kautta: <xliff:g id="VPN_APP">%1$s</xliff:g>. Verkkotoimintasi, mukaan lukien sähköpostit ja selausdata, näkyy VPN-palveluntarjoajalle."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Avaa VPN-asetukset"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Vanhempasi ylläpitää tätä laitetta. Vanhempasi voi nähdä ja ylläpitää tietoja, esim. käyttämiäsi sovelluksia, sijaintiasi ja käyttöaikaasi."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ota käyttöön, jos akku todennäköisesti loppuu"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ei kiitos"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Luo SysUI-keon vedos"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> ovat sovellusten käytössä."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Lähetyksen nimi"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Salasana"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Tallenna"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Aloitetaan…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei voi lähettää"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 4058db7..20da045 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de faire une autre capture d\'écran"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Partagez la capture d\'écran"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> possède cet appareil et peut contrôler le trafic réseau"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Cet appareil appartient à votre organisation et est connecté à Internet par l\'intermédiaire de RPV"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet par l\'intermédiaire de RPV"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Votre organisation peut contrôler le trafic réseau dans votre profil professionnel"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> peut contrôler votre trafic réseau dans votre profil professionnel"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Votre administrateur informatique a accès à l\'activité sur le réseau de votre profil professionnel"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Le réseau peut être surveillé"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Cet appareil est connecté à Internet par l\'intermédiaire de RPV"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion d\'appareils"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"RPV"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Votre administrateur a activé la journalisation réseau, qui surveille le trafic sur votre appareil."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Votre administrateur a activé la journalisation réseau, qui surveille le trafic dans votre profil professionnel, mais pas dans votre profil personnel."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP_0">%1$s</xliff:g> et de <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau dans les applications professionnelles, y compris les courriels et les données de navigation, est visible par votre administrateur informatique et par votre fournisseur de RPV."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre fournisseur de RPV."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ouvrir les paramètres RPV"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applications que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Maintenu déverrouillé par TrustAgent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Paramètres sonores"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Aj. auto. s-titres aux médias"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sous-titrer automatiquement"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Astuce concernant les sous-titres"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Superposition de sous-titres"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"activer"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Activer si la pile est susceptible de s\'épuiser totalement"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Non merci"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nom de diffusion"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Mot de passe"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Enregistrer"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Démarrage en cours…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
@@ -890,7 +884,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"Le contenu sera bientôt affiché"</string>
<string name="missed_call" msgid="4228016077700161689">"Appel manqué"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"Affichez les messages récents, les appels manqués et les mises à jour d\'état"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"Afficher les messages récents, les appels manqués et les mises à jour d\'état"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"Interrompue par la fonctionnalité Ne pas déranger"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message : <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 6d29da6..8e47283 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de nouveau de faire une capture d\'écran"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Les captures d\'écran ne sont pas autorisées par l\'application ni par votre organisation"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Partager la capture d\'écran"</string>
@@ -334,7 +336,7 @@
<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="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
- <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
+ <string name="guest_wipe_session_title" msgid="7147965814683990944">"Heureux de vous revoir, 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>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, qui peut contrôler votre trafic réseau"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Cet appareil appartient à votre organisation et est connecté à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Cet appareil appartient à votre organisation"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Cet appareil appartient à votre organisation et est connecté à Internet via des VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> et est connecté à Internet via des VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Votre entreprise peut contrôler votre trafic réseau dans votre profil professionnel"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> peut contrôler votre trafic réseau dans votre profil professionnel"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Votre administrateur IT peut voir l\'activité sur le réseau de votre profil professionnel"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Il est possible que le réseau soit surveillé"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Cet appareil est connecté à Internet via des VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applis professionnelles sont connectées à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applis personnelles sont connectées à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Cet appareil est connecté à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion des appareils"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Votre administrateur a activé la journalisation du réseau, pour contrôler le trafic sur votre appareil."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Votre administrateur a activé la journalisation réseau, qui surveille le trafic de votre profil professionnel, mais pas celui de votre profil personnel."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Cet appareil est connecté à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre administrateur informatique a accès à votre activité réseau (e-mails, données de navigation, etc.)."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Cet appareil est connecté à Internet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> et <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Votre administrateur informatique a accès à votre activité réseau (e-mails, données de navigation, etc.)."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applis professionnelles sont connectées à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre administrateur informatique et votre fournisseur de VPN ont accès à votre activité réseau dans les applis professionnelles (e-mails, données de navigation, etc.)."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applis personnelles sont connectées à Internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre fournisseur de VPN a accès à votre activité réseau (e-mails, données de navigation, etc.)."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ouvrir les paramètres VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par tes parents. Ils peuvent voir et gérer certaines informations, telles que les applications que tu utilises, ta position et ton temps d\'utilisation de l\'appareil."</string>
@@ -417,7 +407,7 @@
<string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Maintenu déverrouillé par TrustAgent"</string>
<string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="accessibility_volume_settings" msgid="1458961116951564784">"Paramètres audio"</string>
- <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sous-titres automatiques"</string>
+ <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sous-titrer automatiquement"</string>
<string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Fermer l\'info-bulle des sous-titres"</string>
<string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Sous-titres en superposition"</string>
<string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"activer"</string>
@@ -459,7 +449,7 @@
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"activer le vibreur"</string>
<string name="volume_dialog_title" msgid="6502703403483577940">"Commandes de volume %s"</string>
- <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Sons activés pour les appels et les notifications (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
+ <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Les appels et les notifications sonneront (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
<string name="status_bar" msgid="4357390266055077437">"Barre d\'état"</string>
<string name="demo_mode" msgid="263484519766901593">"Mode de démonstration de l\'interface du système"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Activer l\'économiseur de batterie si l\'autonomie restante risque d\'être insuffisante"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Non, merci"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Copier mémoire SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nom de l\'annonce"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Mot de passe"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Enregistrer"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Démarrage…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
@@ -926,7 +920,7 @@
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter le bloc suivant aux Réglages rapides"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter le bloc"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter bloc"</string>
- <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir utilisateur"</string>
+ <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir l\'utilisateur"</string>
<plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
<item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> appli est active</item>
<item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applis sont actives</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 4cbb066..ea120d2 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Volve tentar crear unha captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Non se puido gardar a captura de pantalla"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A aplicación ou a túa organización non permite realizar capturas de pantalla"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar a captura de pantalla"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é a organización propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence á túa organización e está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a Internet a través de <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence á túa organización"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence á túa organización e está conectado a Internet a través de varias VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado a Internet a través de varias VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"A túa organización pode controlar o tráfico de rede do teu perfil de traballo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode controlar o tráfico de rede do teu perfil de traballo"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"O teu administrador de TI pode ver a actividade de rede do perfil de traballo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"É posible que se controle a rede"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado a Internet a través de varias VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"As túas aplicacións do traballo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"As túas aplicacións persoais están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> proporciona este dispositivo"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Xestión de dispositivos"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Este dispositivo ten unha autoridade de certificación instalada. É posible que se controle ou se modifique o teu tráfico de rede segura."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"O administrador activou o rexistro na rede, que controla o tráfico do teu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"O administrador activou o rexistro na rede, que supervisa o tráfico do teu perfil de traballo, pero non o do perfil persoal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. O teu administrador de TI pode ver a actividade que levas a cabo na rede (por exemplo, os correos electrónicos e os datos de navegación)."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está conectado a Internet a través de <xliff:g id="VPN_APP_0">%1$s</xliff:g> e de <xliff:g id="VPN_APP_1">%2$s</xliff:g>. O teu administrador de TI pode ver a actividade que levas a cabo na rede (por exemplo, os correos electrónicos e os datos de navegación)."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"As túas aplicacións do traballo están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. O teu administrador de TI e o fornecedor da VPN poden ver a actividade que levas a cabo na rede a través das aplicacións do traballo (por exemplo, os correos electrónicos e os datos de navegación)."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"As túas aplicacións persoais están conectadas a Internet a través de <xliff:g id="VPN_APP">%1$s</xliff:g>. O fornecedor da VPN pode ver a actividade que levas a cabo na rede (por exemplo, os correos electrónicos e os datos de navegación)."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configuración da VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"O teu pai ou nai xestiona este dispositivo e pode ver e xestionar información como as aplicacións que usas, a túa localización e o tempo diante da pantalla."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Activa a función se prevés que a batería pode esgotarse"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Non, grazas"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Baleirado mem. SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hai aplicacións que están utilizando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome da difusión"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Contrasinal"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Gardar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Non se puido iniciar a emisión"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 379632a..ab51eed 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ફરીથી સ્ક્રીનશૉટ લેવાનો પ્રયાસ કરો"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"સ્ક્રીનશૉટ સાચવી શકાતો નથી"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશૉટ લેવાની મંજૂરી નથી"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ફેરફાર કરો"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"સ્ક્રીનશૉટમાં ફેરફાર કરો"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"સ્ક્રીનશૉટ શેર કરો"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"તમારી સંસ્થા આ ડિવાઇસની માલિકી ધરાવે છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા પ્રદાન કરવામાં આવેલું છે"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે અને <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને <xliff:g id="VPN_APP">%2$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે અને VPNs મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ની માલિકીનું છે અને VPNs મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"તમારી સંસ્થા તમારી કાર્ય પ્રોફાઇલમાં નેટવર્ક ટ્રાફિકનું નિયમન કરી શકે છે"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> તમારી કાર્ય પ્રોફાઇલમાં નેટવર્ક ટ્રાફિકનું નિયમન કરી શકે છે"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ઑફિસ માટેની ઍપની નેટવર્ક પ્રવૃત્તિને તમારા IT વ્યવસ્થાપક જોઈ શકે છે"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"નેટવર્કનું નિયમન કરવામાં આવી શકે છે"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"આ ડિવાઇસ VPNs મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"તમારી ઑફિસ માટેની ઍપ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"તમારી વ્યક્તિગત ઍપ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"આ ડિવાઇસ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા પ્રદાન કરવામાં આવેલું છે"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ડિવાઇસ મેનેજમેન્ટ"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કરેલ છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગિંગ ચાલુ કર્યું છે, જે તમારા ઉપકરણ પર નેટવર્ક ટ્રાફિકનું નિયમન કરે છે."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગ ઇન ચાલુ કર્યું છે, જે તમારી વ્યક્તિગત પ્રોફાઇલમાં નહીં, પરંતુ ઑફિસની પ્રોફાઇલમાં ટ્રાફિકનું નિરીક્ષણ કરે છે."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"આ ડિવાઇસ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે. ઇમેઇલ અને બ્રાઉઝિંગ ડેટા સહિતની તમારી નેટવર્ક પ્રવૃત્તિ, તમારા IT ઍડમિન જોઈ શકે છે."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"આ ડિવાઇસ <xliff:g id="VPN_APP_0">%1$s</xliff:g> અને <xliff:g id="VPN_APP_1">%2$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે. ઇમેઇલ અને બ્રાઉઝિંગ ડેટા સહિતની તમારી નેટવર્ક પ્રવૃત્તિ, તમારા IT ઍડમિન જોઈ શકે છે."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"તમારી ઑફિસ માટેની ઍપ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે. ઇમેઇલ અને બ્રાઉઝિંગ ડેટા સહિતની ઑફિસ માટેની ઍપમાંની તમારી નેટવર્ક પ્રવૃત્તિ, તમારા IT ઍડમિન અને VPN પ્રદાતા જોઈ શકે છે."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"તમારી વ્યક્તિગત ઍપ <xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે ઇન્ટરનેટ સાથે કનેક્ટેડ છે. ઇમેઇલ અને બ્રાઉઝિંગ ડેટા સહિતની તમારી નેટવર્ક પ્રવૃત્તિ, તમારા VPN પ્રદાતા જોઈ શકે છે."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN સેટિંગ ખોલો"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે. તમે જેનો ઉપયોગ કરો છો તે ઍપ, તમારું સ્થાન અને તમારા સ્ક્રીન સમય જેવી માહિતીને તમારા માતાપિતા જોઈ અને મેનેજ કરી શકે છે."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"જ્યારે બૅટરી સંભવિત રૂપે પૂરી થવામાં હોય ત્યારે બૅટરી સેવર ચાલુ કરો"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ના, આભાર"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ઍપ્લિકેશન તમારા <xliff:g id="TYPES_LIST">%s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" અને "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"સાચવો"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"શરૂ થઈ રહ્યું છે…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"બ્રોડકાસ્ટ કરી શકતા નથી"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
@@ -888,7 +884,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"ટૂંક સમયમાં કન્ટેન્ટ બતાવવામાં આવશે"</string>
<string name="missed_call" msgid="4228016077700161689">"ચૂકી ગયેલો કૉલ"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના સંદેશા, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના મેસેજ, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string>
<string name="people_tile_title" msgid="6589377493334871272">"વાતચીત"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"\'ખલેલ પાડશો નહીં\'ની સુવિધા દ્વારા થોભાવેલું"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ સંદેશ મોકલવામાં આવ્યો: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml
index 1d6f279..e6af6f4 100644
--- a/packages/SystemUI/res/values-h800dp/dimens.xml
+++ b/packages/SystemUI/res/values-h800dp/dimens.xml
@@ -16,7 +16,7 @@
<resources>
<!-- Minimum margin between clock and top of screen or ambient indication -->
- <dimen name="keyguard_clock_top_margin">38dp</dimen>
+ <dimen name="keyguard_clock_top_margin">26dp</dimen>
<!-- Large clock maximum font size (dp is intentional, to prevent any further scaling) -->
<dimen name="large_clock_text_size">200dp</dimen>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f1ea573..80e51c2 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रीनशॉट दोबारा लेने की कोशिश करें"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"स्क्रीनशॉट को सेव नहीं किया जा सकता"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ऐप्लिकेशन या आपका संगठन स्क्रीनशॉट लेने की अनुमति नहीं देता"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"बदलाव करें"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रीनशॉट में बदलाव करें"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेयर करें"</string>
@@ -335,7 +337,7 @@
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
<string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string>
- <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्या आप अपना सत्र जारी रखना चाहते हैं?"</string>
+ <string name="guest_wipe_session_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_limit_reached_title" msgid="2429229448830346057">"अब और उपयोगकर्ता नहीं जोड़े जा सकते"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने दिया है"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"यह डिवाइस आपके संगठन का है. इसे <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> का है. इसे <xliff:g id="VPN_APP">%2$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"यह डिवाइस आपके संगठन का है. इसे वीपीएन के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> का है. इसे वीपीएन के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"आपका संगठन आपकी वर्क प्रोफ़ाइल में नेटवर्क ट्रैफ़िक की निगरानी कर सकता है"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपकी वर्क प्रोफ़ाइल में नेटवर्क ट्रैफ़िक की निगरानी कर सकता है"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"आईटी एडमिन आपकी वर्क प्रोफ़ाइल के नेटवर्क से जुड़ी गतिविधि देख सकता है"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"नेटवर्क की निगरानी की जा सकती है"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"इस डिवाइस को वीपीएन के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ऑफ़िस के काम से जुड़े आपके ऐप्लिकेशन, <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किए गए हैं"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"आपके निजी ऐप्लिकेशन, <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किए गए हैं"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"यह डिवाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने दिया है"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिवाइस मैनेजमेंट"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"वीपीएन"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपके व्यवस्थापक ने नेटवर्क लॉगिंग चालू किया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"आपके एडमिन ने नेटवर्क लॉगिंग की सुविधा चालू कर दी है. इससे आपकी वर्क प्रोफ़ाइल पर आने वाले ट्रैफ़िक की निगरानी की जाती है. हालांकि, इससे आपकी निजी प्रोफ़ाइल की निगरानी नहीं की जाती."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, आपके आईटी एडमिन को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"इस डिवाइस को <xliff:g id="VPN_APP_0">%1$s</xliff:g> और <xliff:g id="VPN_APP_1">%2$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, आपके आईटी एडमिन को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन, <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किए गए हैं. ऑफ़िस के काम से जुड़े ऐप्लिकेशन में, नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी आपके आईटी एडमिन और वीपीएन सेवा देने वाले को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"आपके निजी ऐप्लिकेशन, <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किए गए हैं. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, वीपीएन सेवा देने वाले को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN सेटिंग खोलें"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं. अभिभावक आपके डिवाइस से जुड़ी जानकारी देख सकते हैं. साथ ही, इसे प्रबंधित कर सकते हैं. इनमें आपके इस्तेमाल किए गए ऐप्लिकेशन, जगह की जानकारी, और डिवाइस के इस्तेमाल में बिताए गए समय जैसी जानकारी शामिल है."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"जब बैटरी खत्म होने वाली हो तब \'बैटरी सेवर\' चालू करें"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"जी नहीं, शुक्रिया"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ऐप्लिकेशन आपकी <xliff:g id="TYPES_LIST">%s</xliff:g> का इस्तेमाल कर रहे हैं."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" और "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ब्रॉडकास्ट का नाम"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"पासवर्ड"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेव करें"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"शुरू हो रहा है…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट नहीं किया जा सकता"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index cac79b0..f858fc7 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pokušajte ponovo napraviti snimku zaslona"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nije moguće spremiti snimku zaslona"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ili vaša organizacija ne dopuštaju snimanje zaslona"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Uređivanje snimke zaslona"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Podijeli snimku zaslona"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlasnik je ovog uređaja i može nadzirati mrežni promet"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ovaj uređaj pruža organizacija <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Uređaj pripada vašoj organizaciji i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem aplikacije <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ovaj uređaj pripada vašoj organizaciji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Uređaj pripada vašoj organizaciji i povezan je s internetom putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i povezan je s internetom putem VPN-ova"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija može nadzirati mrežni promet na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> može nadzirati mrežni promet na vašem radnom profilu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Mrežna aktivnost poslovnog profila vidljiva je vašem IT administratoru"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mreža se možda nadzire"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Uređaj je povezan s internetom putem VPN-ova"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše poslovne aplikacije povezane su s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Osobne su aplikacije povezane s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Uređaj je povezan s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ovaj uređaj pruža <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje uređajem"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Na ovom je uređaju instaliran izdavač certifikata. Vaš sigurni mrežni promet možda se nadzire ili modificira."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator je uključio mrežni zapisnik koji nadzire promet na vašem uređaju."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio mrežni zapisnik koji prati promet na vašem poslovnom profilu, ali ne i na osobnom profilu."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Uređaj je povezan s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaše aktivnosti na mreži, uključujući e-poruke i podatke o pregledavanju, vidljive su IT administratoru."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Uređaj je povezan s internetom putem aplikacija <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaše aktivnosti na mreži, uključujući e-poruke i podatke o pregledavanju, vidljive su IT administratoru."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Poslovne aplikacije povezane su s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaše aktivnosti na mreži u poslovnim aplikacijama, uključujući e-poruke i podatke o pregledavanju, vidljive su IT administratoru i davatelju VPN usluga."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Osobne su aplikacije povezane s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaše aktivnosti na mreži, uključujući e-poruke i podatke o pregledavanju, vidljive su davatelju VPN usluga."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvorite postavke VPN-a"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja tvoj roditelj. Tvoj roditelj može vidjeti podatke kao što su aplikacije kojima se koristiš, lokaciju i vrijeme upotrebe te upravljati njima."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Uključite kad bi se baterija mogla isprazniti"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izdvoji mem. SysUI-a"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
@@ -861,9 +853,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Naziv emitiranja"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Zaporka"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Spremi"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pokretanje…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitiranje nije uspjelo"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
@@ -892,7 +886,7 @@
<string name="audio_status" msgid="4237055636967709208">"Slušanje"</string>
<string name="game_status" msgid="1340694320630973259">"Igranje"</string>
<string name="empty_user_name" msgid="3389155775773578300">"Prijatelji"</string>
- <string name="empty_status" msgid="5938893404951307749">"Može chat večeras?"</string>
+ <string name="empty_status" msgid="5938893404951307749">"Čujemo se večeras?"</string>
<string name="status_before_loading" msgid="1500477307859631381">"Sadržaj će se uskoro prikazati"</string>
<string name="missed_call" msgid="4228016077700161689">"Propušteni poziv"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index dcb0db1..7f963b1 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Próbálja meg újra elkészíteni a képernyőképet"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nem lehetséges a képernyőkép mentése"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Az alkalmazás vagy az Ön szervezete nem engedélyezi képernyőkép készítését"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Szerkesztés"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Képernyőkép szerkesztése"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Képernyőkép megosztása"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Ezt az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> szervezet biztosítja"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ez az eszköz az Ön szervezete tulajdonában van, és ezen keresztül csatlakozik az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és a következőn keresztül csatlakozik az internethez: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ez az eszköz az Ön szervezete tulajdonában van, és VPN-eken keresztül csatlakozik az internethez"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tulajdonában van, és VPN-eken keresztül csatlakozik az internethez"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Szervezete figyelheti a munkaprofil hálózati forgalmát"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"A(z) <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> figyelheti a munkaprofil hálózati forgalmát"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Munkaprofilja hálózati tevékenységét láthatja a rendszergazdája"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Elképzelhető, hogy a hálózatot figyelik"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ez az eszköz VPN-eken keresztül csatlakozik az internethez"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Munkahelyi alkalmazásai a következő VPN-alkalmazáson keresztül csatlakoznak az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Személyes alkalmazásai a következőn keresztül csatlakoznak az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ez az eszköz a következőn keresztül csatlakozik az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Ezt az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> szervezet biztosítja"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Eszközkezelés"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Az eszközre tanúsítványkibocsátó van telepítve. Ezáltal figyelhetik és befolyásolhatják az Ön biztonságos hálózati forgalmát."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"A rendszergazda bekapcsolta az eszköz forgalmát figyelő hálózati naplózást."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"A rendszergazda bekapcsolta a hálózati naplózást, amely a munkaprofilban figyeli a forgalmat, a személyes profilban azonban nem."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ez az eszköz a következőn keresztül csatlakozik az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>. Hálózati tevékenységei (pl. az e-mailek és a böngészési adatok) láthatók a rendszergazdája és VPN-szolgáltatója számára."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ez az eszköz a következőkön keresztül csatlakozik az internethez: <xliff:g id="VPN_APP_0">%1$s</xliff:g> és <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Hálózati tevékenységei (pl. az e-mailek és a böngészési adatok) láthatók a rendszergazdája és VPN-szolgáltatója számára."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Munkahelyi alkalmazásai a következőn keresztül csatlakoznak az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>. A munkahelyi alkalmazásaiban végzett hálózati tevékenységei (pl. az e-mailek és a böngészési adatok) láthatók a rendszergazdája és VPN-szolgáltatója számára."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Személyes alkalmazásai a következőn keresztül csatlakoznak az internethez: <xliff:g id="VPN_APP">%1$s</xliff:g>. Hálózati tevékenységei (pl. az e-mailek és a böngészési adatok) láthatók a VPN-szolgáltatója számára."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN-beállítások megnyitása"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Az eszközt a szülőd felügyeli. A szülőd megtekintheti és kezelheti például a használt alkalmazásokra, a tartózkodási helyre és a képernyőidőre vonatkozó adatokat."</string>
@@ -730,11 +720,13 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Kapcsolja be, ha az akkumulátor hamarosan lemerül"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nem"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI-memória-kiírás"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Több alkalmazás használja a következőket: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" és "</string>
- <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Jelenleg a következő használja: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Legutóbb a következő használta: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"Jelenleg használja: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="2736290123662790026">"Legutóbb használta: <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
<string name="ongoing_privacy_dialog_enterprise" msgid="3003314125311966061">"(munkahely)"</string>
<string name="ongoing_privacy_dialog_phonecall" msgid="4487370562589839298">"Telefonhívás"</string>
<string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(a következőn keresztül: <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Közvetítés neve"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Jelszó"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Mentés"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Indítás…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nem sikerült a közvetítés"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 6dc481c..c3fe39d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Փորձեք նորից"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Չհաջողվեց պահել սքրինշոթը"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում սքրինշոթի ստացումը"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Փոփոխել"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Փոփոխել սքրինշոթը"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Ուղարկել սքրինշոթ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"«<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Այս սարքը տրամադրվել է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> կազմակերպության կողմից"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Այս սարքը պատկանում է ձեր կազմակերպությանը և համացանցին միացած է <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Այս սարքը պատկանում է <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպությանը և համացանցին միացած է <xliff:g id="VPN_APP">%2$s</xliff:g>-ի միջոցով"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>» կազմակերպությանը"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Այս սարքը պատկանում է ձեր կազմակերպությանը և համացանցին միացած է VPN-ների միջոցով"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Այս սարքը պատկանում է <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպությանը և համացանցին միացած է VPN-ների միջոցով"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ձեր կազմակերպությունը կարող է վերահսկել ձեր աշխատանքային պրոֆիլի ցանցային թրաֆիկը"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> կազմակերպությունը կարող է վերահսկել ձեր աշխատանքային պրոֆիլի ցանցային թրաֆիկը"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Աշխատանքային պրոֆիլով կատարված գործողությունները տեսանելի են ՏՏ ադմինիստրատորին"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Ցանցը կարող է վերահսկվել"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Այս սարքը համացանցին միացած է VPN-ների միջոցով"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ձեր աշխատանքային հավելվածները համացանցին միացած են <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Անձնական հավելվածները համացանցին միացած են <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Այս սարքը համացանցին միացած է <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Այս սարքը տրամադրվել է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> կազմակերպության կողմից"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Սարքերի կառավարում"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Այս սարքում տեղադրված է վկայագրման կենտրոն։ Ձեր ցանցի ապահով թրաֆիկը կարող է վերահսկվել կամ փոփոխվել։"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Ձեր ադմինիստրատորը միացրել է ցանցային իրադարձությունների գրանցումը, որը վերահսկում է ձեր սարքի թրաֆիկը։"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Ձեր ադմինիստրատորը միացրել է ցանցային իրադարձությունների գրանցումը, որը վերահսկում է ձեր աշխատանքային պրոֆիլի թրաֆիկը (այլ ոչ անձնական պրոֆիլը)։"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Այս սարքը միացած է համացանցին <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով։ Ձեր ցանցային գործողությունները աշխատանքային հավելվածներում, ներառյալ էլփոստում և դիտարկիչում արված գործողությունների տվյալները, տեսանելի են ձեր ՏՏ ադմինիստրատորին։"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Այս սարքը համացանցին միացած է <xliff:g id="VPN_APP_0">%1$s</xliff:g>-ի և <xliff:g id="VPN_APP_1">%2$s</xliff:g>-ի միջոցով։ Ձեր ցանցային գործողությունները աշխատանքային հավելվածներում, ներառյալ էլփոստում և դիտարկիչում արված գործողությունների տվյալները, տեսանելի են ձեր ՏՏ ադմինիստրատորին։"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Աշխատանքային հավելվածները համացանցին միացած են <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով։ Ձեր ցանցային գործողությունները աշխատանքային հավելվածներում, ներառյալ էլփոստում և դիտարկիչում արված գործողությունների տվյալները, տեսանելի են ձեր ՏՏ ադմինիստրատորին և VPN-ի մատակարարին։"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Անձնական հավելվածները համացանցին միացած են <xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով։ Ձեր ցանցային գործողությունները անձնական հավելվածներում, ներառյալ էլփոստում և դիտարկիչում արված գործողությունների տվյալները, տեսանելի են ձեր VPN-ի մատակարարին։"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Բացել VPN-ի կարգավորումները"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Այս սարքը կառավարում է ձեր ծնողը։ Նա կարող է դիտել և փոփոխել որոշակի տեղեկություններ, օրինակ՝ հավելվածները, որոնք դուք օգտագործում եք, ձեր տեղադրությունը և սարքի օգտագործման ժամանակը։"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Միացնել էներգախնայումը, երբ մարտկոցի լիցքը գրեթե սպառված է"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ոչ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" և "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Հեռարձակման անվանումը"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Գաղտնաբառ"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Պահել"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Սկսվում է…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Չհաջողվեց հեռարձակել"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 8a16afb..67400b9 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Coba ambil screenshot lagi"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Tidak dapat menyimpan screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Mengambil screenshot tidak diizinkan oleh aplikasi atau organisasi"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Mengedit screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Bagikan screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi Anda memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Perangkat ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Perangkat ini milik organisasi Anda dan terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan terhubung ke internet melalui <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Perangkat ini milik organisasi Anda"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Perangkat ini milik organisasi Anda dan terhubung ke internet melalui beberapa VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan terhubung ke internet melalui beberapa VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasi dapat memantau traffic jaringan di profil kerja"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mungkin memantau traffic jaringan di profil kerja Anda"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivitas jaringan profil kerja dapat dilihat oleh admin IT Anda"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Jaringan mungkin dipantau"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Perangkat ini terhubung ke internet melalui beberapa VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Aplikasi kerja terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Aplikasi pribadi Anda terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Perangkat ini terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Perangkat ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengelolaan perangkat"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Otoritas sertifikat diinstal di perangkat. Traffic jaringan aman Anda mungkin dipantau atau diubah."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Admin telah mengaktifkan pencatatan log jaringan, yang memantau traffic di perangkat."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Admin telah mengaktifkan pencatatan log jaringan, yang memantau traffic di profil kerja, tetapi tidak di profil pribadi."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Perangkat ini terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktivitas jaringan Anda, termasuk email dan data penjelajahan, dapat dilihat oleh admin IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Perangkat ini terhubung ke internet melalui <xliff:g id="VPN_APP_0">%1$s</xliff:g> dan <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Aktivitas jaringan Anda, termasuk email dan data penjelajahan, dapat dilihat oleh admin IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Aplikasi kerja Anda terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktivitas jaringan Anda di aplikasi kerja, termasuk email dan data penjelajahan, dapat dilihat oleh admin IT dan penyedia VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Aplikasi pribadi Anda terhubung ke internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktivitas jaringan Anda, termasuk email dan data penjelajahan, dapat dilihat oleh penyedia VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Buka setelan VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Perangkat ini dikelola oleh orang tuamu. Orang tuamu bisa melihat dan mengelola berbagai informasi, seperti aplikasi yang kamu gunakan, lokasimu, dan lama pemakaian perangkat."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktifkan jika daya baterai kemungkinan akan habis"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Tidak, terima kasih"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Hapus Heap SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nama Siaran"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Sandi"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Simpan"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Memulai …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat menyiarkan"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 9a04585..233fc17 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prófaðu að taka skjámynd aftur"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekki er hægt að vista skjámynd"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Forritið eða fyrirtækið þitt leyfir ekki skjámyndatöku"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Breyta"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Breyta skjámynd"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Deila skjámynd"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> á þetta tæki og fylgist hugsanlega með netumferð"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Þetta tæki er frá <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Þetta tæki tilheyrir fyrirtækinu þínu og er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er nettengt í gegnum <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Þetta tæki tilheyrir fyrirtækinu þínu og er nettengt í gegnum VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er nettengt í gegnum VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Fyrirtækið þitt kann að fylgjast með netnotkun á vinnusniðinu þínu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kann að fylgjast með netnotkun á vinnusniðinu þínu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Kerfisstjóri getur séð netvirkni á vinnusniðinu þínu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Hugsanlega er fylgst með netinu"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Þetta tæki er nettengt í gegnum VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vinnuforritin þín eru nettengd í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Forritin þín til einkanota eru nettengd í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Þetta tæki er frá <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Tækjastjórnun"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -398,18 +392,14 @@
<string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"Mögulegt er að <xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> fái aðgang að gögnum sem tengjast þessu tæki, geti stjórnað forritum og breytt stillingum tækisins.\n\nEf spurningar vakna skaltu hafa samband við <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
<string name="monitoring_description_management" msgid="4308879039175729014">"Þetta tæki tilheyrir fyrirtækinu þínu.\n\nKerfisstjórinn getur fylgst með og breytt stillingum, fyrirtækjaaðgangi, forritum, gögnum sem tengjast tækinu þínu og staðsetningarupplýsingum tækisins.\n\nHafðu samband við kerfisstjórann til að fá frekari upplýsingar."</string>
<string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Fyrirtækið þitt setti upp CA-vottorð á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
- <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Fyrirtækið þitt setti upp CA-vottorð á vinnusniðinu þínu. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
+ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Fyrirtækið þitt setti upp CA-vottorð á vinnuprófílnum þínum. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA-vottorð er uppsett á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Kerfisstjóri hefur kveikt á eftirliti netkerfa, sem fylgist með netumferð á tækinu þínu."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Stjórnandinn kveikti á eftirliti netkerfa sem fylgist með netumferð á vinnusniðinu þínu en ekki á eigin sniði."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. Kerfisstjórinn þinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Kerfisstjórinn þinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vinnuforritin þín eru nettengd í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. Kerfisstjórinn þinn og VPN-þjónustuaðilinn geta séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Forritin þín til einkanota eru nettengd í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. VPN-þjónustuaðilinn þinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Opna VPN-stillingar"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Foreldri þitt stjórnar þessu tæki. Foreldri þitt getur séð og stjórnað upplýsingum eins og forritunum sem þú notar, staðsetningu þinni og skjátímanum."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Kveikja þegar rafhlaða er við það að klárast"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nei, takk"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Vista SysUI-gögn"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Forrit eru að nota <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Heiti útsendingar"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Aðgangsorð"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Vista"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Ræsir…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ekki hægt að senda út"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 4309653..d5ad8ad 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Riprova ad acquisire lo screenshot"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossibile salvare lo screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifica"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifica screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Condividi screenshot"</string>
@@ -334,7 +336,7 @@
<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="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
- <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string>
+ <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto nella 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>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, che potrebbe monitorare il traffico di rete"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Questo dispositivo è fornito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Questo dispositivo appartiene alla tua organizzazione e si connette a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e si connette a Internet tramite <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Questo dispositivo appartiene alla tua organizzazione"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Questo dispositivo appartiene alla tua organizzazione e si connette a Internet tramite VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e si connette a Internet tramite VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"La tua organizzazione potrebbe monitorare il traffico di rete nel tuo profilo di lavoro"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> potrebbe monitorare il traffico di rete nel tuo profilo di lavoro"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"L\'attività di rete del tuo profilo di lavoro è visibile all\'amministratore IT"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"La rete potrebbe essere monitorata"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Questo dispositivo si connette a Internet tramite VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Le tue app di lavoro si connettono a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Le tue app personali si connettono a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Questo dispositivo si connette a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Questo dispositivo è fornito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestione dei dispositivi"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sul dispositivo è installata un\'autorità di certificazione. Il tuo traffico di rete protetto potrebbe essere monitorato o modificato."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"L\'amministratore ha attivato i log di rete, che consentono di monitorare il traffico sul dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"L\'amministratore ha attivato i log di rete, che consentono di monitorare il traffico nel profilo di lavoro, ma non nel profilo personale."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Questo dispositivo si connette a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>. La tua attività di rete, inclusi email e dati di navigazione, è visibile all\'amministratore IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Questo dispositivo si connette a Internet tramite <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. La tua attività di rete, inclusi email e dati di navigazione, è visibile all\'amministratore IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Le tue app di lavoro si connettono a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>. La tua attività di rete nelle app di lavoro, inclusi email e dati di navigazione, è visibile all\'amministratore IT e al provider VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Le tue app personali si connettono a Internet tramite <xliff:g id="VPN_APP">%1$s</xliff:g>. La tua attività di rete nelle app personali, inclusi email e dati di navigazione, è visibile al provider VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Apri impostazioni VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Questo dispositivo è gestito da uno dei tuoi genitori, il quale può visualizzare e gestire informazioni come le app che usi, la tua posizione e il tuo tempo di utilizzo."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Attiva questa funzionalità se è probabile che la batteria si scarichi"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"No grazie"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump heap SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome annuncio"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salva"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Avvio in corso…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossibile trasmettere"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index d79d012..11035de 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"אפשר לצלם שוב את המסך"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"לא ניתן לשמור את צילום המסך"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"האפליקציה או הארגון שלך אינם מתירים ליצור צילומי מסך"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"עריכה"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"עריכת צילום מסך"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"שיתוף של צילום מסך"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"המכשיר הזה התקבל מ-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"המכשיר הזה שייך לארגון שלך, והוא מחובר לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, והוא מחובר לאינטרנט דרך <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"המכשיר הזה שייך לארגון שלך"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"המכשיר הזה שייך לארגון שלך, והוא מחובר לאינטרנט דרך רשתות VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, והוא מחובר לאינטרנט דרך רשתות VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"הארגון שלך יכול לנטר את התנועה ברשת בפרופיל העבודה שלך"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"הארגון <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> עשוי לנטר את התנועה ברשת בפרופיל העבודה שלך"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"מנהל ה-IT יכול לראות את הפעילות ברשת"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ייתכן שהרשת מנוטרת"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"המכשיר הזה מחובר לאינטרנט דרך רשתות VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"האפליקציות לעבודה מחוברות לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"האפליקציות האישיות שלך מחוברות לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"המכשיר הזה מחובר לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"המכשיר הזה התקבל מ-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ניהול מכשירים"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"במכשיר זה מותקנת רשות אישורים. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"מנהל המערכת הפעיל את התכונה \'רישום התנועה ברשת\', שמנטרת את תנועת הנתונים במכשיר."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים בפרופיל העבודה, אבל לא בפרופיל האישי."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"המכשיר הזה מחובר לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>. הפעילויות שלך ברשת, כולל האימיילים ונתוני הגלישה, גלויות למנהל ה-IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"המכשיר הזה מחובר לאינטרנט דרך <xliff:g id="VPN_APP_0">%1$s</xliff:g> ו-<xliff:g id="VPN_APP_1">%2$s</xliff:g>. הפעילויות שלך ברשת, כולל האימיילים ונתוני הגלישה, גלויות למנהל ה-IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"האפליקציות לעבודה מחוברות לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>. הפעילויות שלך ברשת באפליקציות לעבודה, כולל האימיילים ונתוני הגלישה, גלויות למנהל ה-IT ולספק ה-VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"האפליקציות האישיות שלך מחוברות לאינטרנט דרך <xliff:g id="VPN_APP">%1$s</xliff:g>. הפעילויות שלך ברשת, כולל האימיילים ונתוני הגלישה, גלויות לספק ה-VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"להגדרות ה-VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"מכשיר זה מנוהל על ידי ההורה שלך. להורה שלך יש אפשרות לצפות בפרטים כמו האפליקציות שבשימוש, המיקום וזמן המסך שלך, ולנהל אותם."</string>
@@ -589,7 +579,7 @@
<string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"מערכת"</string>
<string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"דף הבית"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"מהזמן האחרון"</string>
- <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"הקודם"</string>
+ <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"חזרה"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"התראות"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"מקשי קיצור במקלדת"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"החלפה של פריסת מקלדת"</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"מומלץ להפעיל את התכונה כשיש סבירות גבוהה שהסוללה תתרוקן"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"לא תודה"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" וגם "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"שם השידור"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"סיסמה"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"שמירה"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"בתהליך הפעלה…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"לא ניתן לשדר"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"מספר Build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"מספר ה-Build הועתק ללוח."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 8ab93db..4b64ddc 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"スクリーンショットを撮り直してください"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"スクリーンショットを保存できません"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"スクリーンショットの作成はアプリまたは組織で許可されていません"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"編集"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"スクリーンショットを編集します"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"スクリーンショットを共有"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"これは組織が所有するデバイスで、<xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、<xliff:g id="VPN_APP">%2$s</xliff:g>を介してインターネットに接続しています"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"これは組織が所有するデバイスです"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスです"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"これは組織が所有するデバイスで、VPN を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"これは <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> が所有するデバイスで、VPN を介してインターネットに接続しています"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"組織は仕事用プロファイルのネットワーク トラフィックを監視することがあります"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> によってこの仕事用プロファイルのネットワーク トラフィックが監視されることもあります"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"仕事用プロファイルのネットワーク アクティビティは IT 管理者に公開されます"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ネットワークが監視されることもあります"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"このデバイスは VPN を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"仕事用アプリは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"個人用アプリは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"このデバイスは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> から提供されています"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"デバイス管理"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"このデバイスには認証局がインストールされています。保護されたネットワーク トラフィックが監視、変更される可能性があります。"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"管理者がネットワーク ログを有効にしているため、このデバイスのトラフィックが監視されています。"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"管理者がネットワーク ログを有効にしているため、仕事用プロファイルのトラフィックは監視されています(個人用プロファイルは対象外)。"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"このデバイスは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています。メールや閲覧データなど、ネットワーク アクティビティは、IT 管理者に公開されます。"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"このデバイスは <xliff:g id="VPN_APP_0">%1$s</xliff:g>と <xliff:g id="VPN_APP_1">%2$s</xliff:g>を介してインターネットに接続しています。メールや閲覧データなど、ネットワーク アクティビティは、IT 管理者に公開されます。"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"仕事用アプリは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています。メールや閲覧データなど、仕事用アプリのネットワーク アクティビティは、IT 管理者と VPN プロバイダに公開されます。"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"個人用アプリは <xliff:g id="VPN_APP">%1$s</xliff:g>を介してインターネットに接続しています。メールや閲覧データなど、ネットワーク アクティビティは、VPN プロバイダに公開されます。"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN 設定を開く"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"このデバイスは保護者によって管理されています。保護者は、あなたが使用するアプリ、あなたの現在地、デバイスの利用時間などの情報を確認したり、管理したりできます。"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"電池切れになる可能性が高くなると有効になります"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"いいえ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ヒープのダンプ"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"アプリは<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しています。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 、 "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ブロードキャストの名前"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"パスワード"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"保存"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"開始しています…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ブロードキャストできません"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 7106b5f..82cd22b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ხელახლა ცადეთ ეკრანის ანაბეჭდის გაკეთება"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ეკრანის ანაბეჭდის შენახვა ვერ ხერხდება"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ეკრანის ანაბეჭდების შექმნა არ არის ნებადართული აპის ან თქვენი ორგანიზაციის მიერ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"რედაქტირება"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ეკრანის ანაბეჭდის რედაქტირება"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ეკრანის ანაბეჭდის გაზიარება"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ამ მოწყობილობის მომწოდებელია <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ეს მოწყობილობა ეკუთვნის თქვენს ორგანიზაციას და დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ეს მოწყობილობა ეკუთვნის <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ორგანიზაციას და დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%2$s</xliff:g> აპით"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ეს მოწყობილობა ეკუთვნის თქვენს ორგანიზაციას დაკავშირებულია ინტერნეტთან VPN-ებით."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ეს მოწყობილობა ეკუთვნის <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ორგანიზაციას და დაკავშირებულია ინტერნეტთან VPN-ებით"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"თქვენს ორგანიზაციას სამსახურის პროფილში ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-ს სამსახურის პროფილში ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"სამსახურის პროფილის ქსელის აქტივობა ხილულია თქვენი IT ადმინისტრატორისთვის"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ქსელზე შესაძლოა ხორციელდებოდეს მონიტორინგი"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან VPN-ებით"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"თქვენი სამსახურის აპები დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"თქვენი პირადი აპები დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ამ მოწყობილობის მომწოდებელია <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"მოწყობილობის მართვა"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ამ მოწყობილობაზე დაინსტალირებულია სერტიფიცირების ორგანო. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"თქვენმა ადმინისტრატორმა ჩართო ქსელის ჟურნალირება, რომელიც თქვენი მოწყობილობის ტრაფიკის მონიტორინგს ახორციელებს."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"თქვენმა ადმინისტრატორმა ქსელის ჟურნალირება ჩართო, რომელიც ახორციელებს თქვენი სამსახურის პროფილის, მაგრამ არა პირადი პროფილის, ტრაფიკის მონიტორინგს."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით. თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია თქვენი IT ადმინისტრატორისთვის."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP_0">%1$s</xliff:g> და <xliff:g id="VPN_APP_1">%2$s</xliff:g> აპებით. თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია თქვენი IT ადმინისტრატორისთვის."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"თქვენი სამსახურის აპები დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით. თქვენი ქსელის აქტივობა სამსახურის აპებში, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია IT ადმინისტრატორისა და VPN პროვაიდერისთვის."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"თქვენი პირადი აპები დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით. თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია VPN პროვაიდერისთვის."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN-ის პარამეტრების გახსნა"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ამ მოწყობილობას თქვენი მშობელი მართავს. თქვენი მშობელი ხედავს და მართავს ისეთ ინფორმაციას, როგორიც არის თქვენ მიერ გამოყენებული აპები, თქვენი მდებარეობა და თქვენ მიერ ეკრანთან გატარებული დრო."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ჩაირთოს, როცა ბატარეა დაცლის პირას არის"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"არა, გმადლობთ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI გროვის გამოტანა"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"აპლიკაციების მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" და "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ტრანსლაციის სახელი"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"პაროლი"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"შენახვა"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"იწყება…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ტრანსლაცია შეუძლებელია"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index d003de8..9ad6bbb 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Қайта скриншот жасап көріңіз"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Скриншотты сақтау мүмкін емес."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Өзгерту"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотты өзгерту"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотты бөлісу"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұсынады."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Бұл құрылғы ұйымыңызға тиесілі және интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі және интернетке <xliff:g id="VPN_APP">%2$s</xliff:g> арқылы қосылған."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Бұл құрылғы ұйымыңызға тиесілі."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі."</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Бұл құрылғы ұйымыңызға тиесілі және интернетке VPN желілері арқылы қосылған."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ұйымына тиесілі және интернетке VPN желілері арқылы қосылған."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ұйымыңыз жұмыс профиліңіздегі желі трафигін бақылауы мүмкін"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> жұмыс профиліңіздегі желі трафигін бақылауы мүмкін"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Желіде жұмыс профилі арқылы не істелгені әкімшіге көрініп тұрады."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Желі бақылануы мүмкін"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Бұл құрылғы интернетке VPN желілері арқылы қосылған."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Жұмыс қолданбаларыңыз интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Жеке қолданбаларыңыз интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Бұл желі интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұсынады"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Құрылғыны басқару"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Осы құрылғыда сертификат орнатылған. Қорғалған желі трафигіңіз бақылануы немесе өзгертілуі мүмкін."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Әкімші құрылғыңыздағы трафикті бақылайтын желі журналын жүргізуді қосқан."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Әкімші жұмыс профиліндегі трафикті (жеке профильдегі трафик қаралмайды) қадағалау үшін желі журналын жүргізуді қосып қойған."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Бұл құрылғы интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған. Желідегі әрекетіңіз, соның ішінде электрондық пошталар мен браузерді пайдалану деректеріңіз әкімшіге көрінеді."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Бұл құрылғы интернетке <xliff:g id="VPN_APP_0">%1$s</xliff:g> және <xliff:g id="VPN_APP_1">%2$s</xliff:g> арқылы қосылған. Желідегі әрекетіңіз, соның ішінде электрондық пошталар мен браузерді пайдалану деректеріңіз әкімшіге көрінеді."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Жұмыс қолданбаларыңыз интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған. Жұмыс қолданбаларында жасаған желідегі әрекетіңіз, соның ішінде электрондық пошталар мен браузерді пайдалану деректеріңіз әкімшіге және VPN провайдеріне көрінеді."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Жеке қолданбаларыңыз интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> арқылы қосылған. Желідегі әрекетіңіз, соның ішінде электрондық пошталар мен браузерді пайдалану деректеріңіз VPN провайдеріне көрінеді."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN параметрлерін ашу"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Бұл құрылғыны ата-анаңыз басқарады. Ата-анаңыз сіз пайдаланатын қолданбалар, геодерегіңіз және пайдалану уақытыңыз сияқты ақпаратты көре және басқара алады."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Батареяның заряды бітуге жақындағанда қосыңыз."</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Жоқ, рақмет"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" және "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Тарату хабарының аты"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Құпия сөз"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сақтау"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Басталып жатыр…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Тарату мүмкін емес"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
@@ -890,7 +884,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"Мазмұн жақында көрсетіледі."</string>
<string name="missed_call" msgid="4228016077700161689">"Өткізіп алған қоңырау"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарларды, өткізіп алған қоңыраулар мен жаңартылған күйлерді көруге болады."</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарлар, өткізіп алған қоңыраулар мен статустың жаңаруы көрсетіледі."</string>
<string name="people_tile_title" msgid="6589377493334871272">"Әңгіме"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"Мазаламау режимі арқылы кідіртілді."</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index be16b12..87862cf 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"សាកល្បងថតរូបថតអេក្រង់ម្តងទៀត"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"មិនអាចរក្សាទុករូបថតអេក្រង់បានទេ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ការថតរូបអេក្រង់មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធីនេះ ឬស្ថាប័នរបស់អ្នក"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"កែ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"កែរូបថតអេក្រង់"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ចែករំលែករូបថតអេក្រង់"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ស្ថាប័នរបស់អ្នកជាម្ចាស់ឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ជាម្ចាស់ឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ឧបករណ៍នេះត្រូវបានផ្ដល់ដោយ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ស្ថាប័នអ្នក និងត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> និងត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ស្ថាប័នអ្នក"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ស្ថាប័នអ្នក និងត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> និងត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ស្ថាប័នរបស់អ្នកអាចនឹងតាមដានចរាចរណ៍បណ្តាញនៅក្នុងកម្រងព័ត៌មានការងាររបស់អ្នក"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> អាចនឹងតាមដានចរាចរណ៍បណ្តាញនៅក្នុងកម្រងព័ត៌មានការងាររបស់អ្នក"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នកអាចមើលឃើញសកម្មភាពបណ្ដាញនៃកម្រងព័ត៌មានការងារ"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"បណ្ដាញអាចត្រូវតាមដាន"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ឧបករណ៍នេះត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"កម្មវិធីការងាររបស់អ្នកត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"កម្មវិធីផ្ទាល់ខ្លួនរបស់អ្នកត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ឧបករណ៍នេះត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ឧបករណ៍នេះត្រូវបានផ្ដល់ដោយ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ការគ្រប់គ្រងឧបករណ៍"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"បានដំឡើងអាជ្ញាធរវិញ្ញាបនបត្រនៅលើឧបករណ៍នេះ។ ចរាចរណ៍បណ្តាញដែលមានសុវត្ថិភាពរបស់អ្នកអាចត្រូវបានតាមដាន ឬកែសម្រួល។"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"អ្នកគ្រប់គ្រងរបស់អ្នកបានបើកការធ្វើកំណត់ហេតុបណ្តាញ ដែលនឹងតាមដានចរាចរណ៍នៅលើឧបករណ៍របស់អ្នក។"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"អ្នកគ្រប់គ្រងរបស់អ្នកបានបើកការធ្វើកំណត់ហេតុបណ្តាញ ដែលតាមដានចរាចរណ៍នៅក្នុងកម្រងព័ត៌មានការងាររបស់អ្នក ប៉ុន្តែមិនតាមដាននៅក្នុងកម្រងព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នកឡើយ។"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ឧបករណ៍នេះត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>។ អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នកអាចមើលឃើញសកម្មភាពបណ្ដាញរបស់អ្នក រួមទាំងអ៊ីមែល និងទិន្នន័យរុករកផងដែរ។"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ឧបករណ៍នេះត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP_0">%1$s</xliff:g> និង <xliff:g id="VPN_APP_1">%2$s</xliff:g>។ អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នកអាចមើលឃើញសកម្មភាពបណ្ដាញរបស់អ្នក រួមទាំងអ៊ីមែល និងទិន្នន័យរុករកផងដែរ។"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"កម្មវិធីការងាររបស់អ្នកត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>។ អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យា និងក្រុមហ៊ុនផ្តល់សេវា VPN របស់អ្នកអាចមើលឃើញសកម្មភាពបណ្ដាញរបស់អ្នកនៅក្នុងកម្មវិធីការងារ រួមទាំងអ៊ីមែល និងទិន្នន័យរុករកផងដែរ។"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"កម្មវិធីផ្ទាល់ខ្លួនរបស់អ្នកត្រូវបានភ្ជាប់អ៊ីនធឺណិតតាមរយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>។ ក្រុមហ៊ុនផ្តល់សេវា VPN របស់អ្នកអាចមើលឃើញសកម្មភាពបណ្ដាញរបស់អ្នក រួមទាំងអ៊ីមែល និងទិន្នន័យរុករកផងដែរ។"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"បើកការកំណត់ VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់មាតាបិតាអ្នក។ មាតាបិតារបស់អ្នកអាចមើល និងគ្រប់គ្រងព័ត៌មានដូចជា កម្មវិធីដែលអ្នកប្រើ ទីតាំងរបស់អ្នក និងរយៈពេលប្រើប្រាស់ឧបករណ៍របស់អ្នកជាដើម។"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"បើកនៅពេលថ្មទំនងជាអស់"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ទេ អរគុណ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"កម្មវិធីកំពុងប្រើ <xliff:g id="TYPES_LIST">%s</xliff:g> របស់អ្នក។"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" និង "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ឈ្មោះការផ្សាយ"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"ពាក្យសម្ងាត់"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"រក្សាទុក"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"កំពុងចាប់ផ្ដើម…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"មិនអាចផ្សាយបានទេ"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខកំណែបង្កើត"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខកំណែបង្កើតទៅឃ្លីបបត។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 4fa0fb9..692e978 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಪುನಃ ತೆಗೆದುಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ಅಪ್ಲಿಕೇಶನ್ ಅಥವಾ ಸಂಸ್ಥೆಯು ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆಯುವುದನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಒದಗಿಸಿದ್ದಾರೆ"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ಈ ಸಾಧನ ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಸ್ವತ್ತಾಗಿದ್ದು, ಇದನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ಈ ಸಾಧನ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನ ಸ್ವತ್ತಾಗಿದ್ದು, ಇದನ್ನು <xliff:g id="VPN_APP">%2$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಗೆ ಸೇರಿದೆ"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ಈ ಸಾಧನ ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಸ್ವತ್ತಾಗಿದ್ದು, ಇದನ್ನು VPN ಗಳ ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ಈ ಸಾಧನ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ನ ಸ್ವತ್ತಾಗಿದ್ದು, ಇದನ್ನು VPN ಗಳ ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ನ ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ನಲ್ಲಿ ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ನೆಟ್ವರ್ಕ್ ಚಟುವಟಿಕೆ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ಗೋಚರಿಸುತ್ತದೆ"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ನೆಟ್ವರ್ಕ್ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದಾಗಿದೆ"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ಈ ಸಾಧನವನ್ನು VPN ಗಳ ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್ಗಳನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ಗಳನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ಈ ಸಾಧನವನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಒದಗಿಸಿದ್ದಾರೆ"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ಸಾಧನ ನಿರ್ವಹಣೆ"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ಈ ಸಾಧನದಲ್ಲಿ ಪ್ರಮಾಣಪತ್ರ ಅಂಗೀಕಾರವನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಸುರಕ್ಷಿತ ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು ಅಥವಾ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನೆಟ್ವರ್ಕ್ ಲಾಗಿಂಗ್ ಆನ್ ಮಾಡಿದ್ದಾರೆ. ಇದು ನಿಮ್ಮ ಸಾಧನದ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನೆಟ್ವರ್ಕ್ ಲಾಗಿಂಗ್ ಆನ್ ಮಾಡಿದ್ದಾರೆ, ಅದು ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ನಲ್ಲಿ ಇರುವ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ನಿಗಾ ಇರಿಸುತ್ತದೆ ಆದರೆ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ನಲ್ಲಿ ಇರುವ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಅಲ್ಲ."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ಈ ಸಾಧನವನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಇಮೇಲ್ಗಳು ಮತ್ತು ಬ್ರೌಸಿಂಗ್ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಚಟುವಟಿಕೆ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ಕಾಣಿಸುತ್ತದೆ."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ಈ ಸಾಧನವನ್ನು <xliff:g id="VPN_APP_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="VPN_APP_1">%2$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಇಮೇಲ್ಗಳು ಮತ್ತು ಬ್ರೌಸಿಂಗ್ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಚಟುವಟಿಕೆ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ಕಾಣಿಸುತ್ತದೆ."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್ಗಳನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಇಮೇಲ್ಗಳು ಮತ್ತು ಬ್ರೌಸಿಂಗ್ ಡೇಟಾ ಸೇರಿದಂತೆ, ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್ಗಳಲ್ಲಿನ ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಚಟುವಟಿಕೆ ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಮತ್ತು VPN ಪೂರೈಕೆದಾರರಿಗೆ ಕಾಣಿಸುತ್ತದೆ."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ಗಳನ್ನು <xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ ಇಂಟರ್ನೆಟ್ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಇಮೇಲ್ಗಳು ಮತ್ತು ಬ್ರೌಸಿಂಗ್ ಡೇಟಾ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಚಟುವಟಿಕೆ ನಿಮ್ಮ VPN ಪೂರೈಕೆದಾರರಿಗೆ ಕಾಣಿಸುತ್ತದೆ."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ. ನೀವು ಬಳಸುವ ಆ್ಯಪ್ಗಳು, ನಿಮ್ಮ ಸ್ಥಳ ಮತ್ತು ನಿಮ್ಮ ವೀಕ್ಷಣಾ ಅವಧಿಯಂತಹ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನೋಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ಬ್ಯಾಟರಿ ಖಾಲಿಯಾಗುವ ಸಾಧ್ಯತೆ ಇದ್ದಾಗ ಆನ್ ಮಾಡಿ"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ಬೇಡ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್ಗಳು ಬಳಸುತ್ತಿವೆ."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ಮತ್ತು "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ಪ್ರಸಾರದ ಹೆಸರು"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"ಪಾಸ್ವರ್ಡ್"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ಉಳಿಸಿ"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ಪ್ರಸಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್ಬೋರ್ಡ್ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 9cf436d..d7628454 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"스크린샷을 다시 찍어 보세요."</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"스크린샷을 저장할 수 없습니다."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"앱이나 조직에서 스크린샷 촬영을 허용하지 않습니다."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"수정"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"스크린샷 수정"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"스크린샷 공유"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 제공하는 기기"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"이 기기는 조직에 속한 기기이며 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"이 기기는 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기이며 <xliff:g id="VPN_APP">%2$s</xliff:g> 앱을 통해 인터넷에 연결됩니다."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"내 조직에 속한 기기입니다."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기입니다."</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"이 기기는 조직에 속한 기기이며 VPN을 통해 인터넷에 연결됩니다."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"이 기기는 <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에 속한 기기이며 VPN을 통해 인터넷에 연결됩니다."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"조직에서 직장 프로필의 네트워크 트래픽을 모니터링할 수 있습니다."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>에서 내 직장 프로필의 네트워크 트래픽을 모니터링할 수 있습니다."</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"직장 프로필의 네트워크 활동은 IT 관리자에게 공개됩니다."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"네트워크가 모니터링될 수 있습니다."</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"이 기기는 VPN을 통해 인터넷에 연결됩니다."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"직장 앱이 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"개인 앱은 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"이 기기는 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 제공하는 기기"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"기기 관리"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"이 기기에는 인증기관이 설치되어 있습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"관리자가 기기에서 발생하는 트래픽을 모니터링하는 네트워크 로깅을 사용 설정했습니다."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"관리자가 직장 프로필에서 발생하는 트래픽을 모니터링하는 네트워크 로깅을 사용 설정했습니다. 하지만 개인 프로필은 모니터링되지 않습니다."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"이 기기는 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"이 기기는 <xliff:g id="VPN_APP_0">%1$s</xliff:g> 및 <xliff:g id="VPN_APP_1">%2$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"직장 앱은 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자와 VPN 제공업체가 이메일, 인터넷 사용 기록 등 직장 앱에서 이루어진 내 네트워크 활동을 볼 수 있습니다."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"개인 앱은 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. VPN 제공업체가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"공개 VPN 설정"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"부모님이 관리하는 기기입니다. 부모님이 내가 사용하는 앱, 내 위치, 기기 사용 시간과 같은 정보를 보고 관리할 수 있습니다."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"배터리가 소진될 것 같으면 사용 설정"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"사용 안함"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"애플리케이션이 <xliff:g id="TYPES_LIST">%s</xliff:g>을(를) 사용 중입니다."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 및 "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"브로드캐스트 이름"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"비밀번호"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"저장"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"시작 중…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"방송할 수 없음"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 1caca3a..0e12705 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Скриншотту кайра тартып көрүңүз"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Скриншот сакталган жок"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Скриншот тартууга колдонмо же ишканаңыз тыюу салган."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Түзөтүү"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотту түзөтүү"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотту бөлүшүү"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык. Уюм тармактын трафигин көзөмөлдөй алат"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Бул түзмөктү <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> камсыздады."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Бул түзмөк уюмуңузга таандык жана Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турат"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык жана Интернетке <xliff:g id="VPN_APP">%2$s</xliff:g> аркылуу туташып турат"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Бул түзмөк уюмуңузга таандык"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Бул түзмөк төмөнкүгө таандык: <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Бул түзмөк уюмуңузга таандык жана Интернетке VPN\'дер аркылуу туташып турат"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> уюмуна таандык жана Интернетке VPN\'дер аркылуу туташып турат"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ишканаңыз жумуш профилиңиздин тармак трафигин көзөмөлдөй алат"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> жумуш профилиңиздеги тармак трафигин көзөмөлдөй алат"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Жумуш профилинин тармактагы аракеттери IT администраторуна көрүнөт"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Тармак көзөмөлдөнүшү мүмкүн"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Бул түзмөк Интернетке VPN\'дер аркылуу туташып турат"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Жумуш колдонмолоруңуз Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турушат"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Жеке колдонмолоруңуз Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турушат"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Бул түзмөк Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турат"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Бул түзмөктү <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> камсыздады."</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Түзмөктү башкаруу"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Бул түзмөктө тастыктоочу борбор орнотулган. Коопсуз тармагыңыздын трафиги көзөмөлдөнүп же өзгөртүлүшү мүмкүн."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администраторуңуз түзмөгүңүздөгү трафикти көзөмөлдөөчү тармактын таржымалын каттоо функциясын иштетти."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администраторуңуз жумуш профилиңиздеги трафикке көз салуу үчүн, тармактын таржымалын иштетип койду (жеке профилиңизден маалымат алынбайт)."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Бул түзмөк Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турат. Тармакта аткарган аракеттериңиз, анын ичинде электрондук каттарыңыз жана серептөө дайындары IT администраторуна көрүнөт."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Бул түзмөк Интернетке <xliff:g id="VPN_APP_0">%1$s</xliff:g> жана <xliff:g id="VPN_APP_1">%2$s</xliff:g> аркылуу туташып турат. Тармакта аткарган аракеттериңиз, анын ичинде электрондук каттарыңыз жана серептөө дайындары IT администраторуна көрүнөт."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Жумуш колдонмолоруңуз Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турушат. Жумуш колдонмолоруңуз аркылуу тармакта аткарган аракеттериңиз, анын ичинде электрондук каттарыңыз жана серептөө дайындары IT администраторуна жана VPN провайдерине көрүнөт."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Жеке колдонмолоруңуз Интернетке <xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу туташып турушат. Тармакта аткарган аракеттериңиз, анын ичинде электрондук каттарыңыз жана серептөө дайындары VPN провайдерине көрүнөт."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN жөндөөлөрүн ачуу"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Бул түзмөктү ата-энең башкарат. Ата-энең сен иштеткен колдонмолорду, кайда жүргөнүңдү жана түзмөктү канча убакыт колдонгонуңду көрүп, башкарып турат."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Батареянын кубаты түгөнүп калганда, күйгүзүлсүн"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Жок, рахмат"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Колдонмолор төмөнкүлөрдү пайдаланып жатышат: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" жана "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Кабарлоонун аталышы"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Сырсөз"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сактоо"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Кабарлап баштады…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Кабарлоого болбойт"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
@@ -869,7 +863,7 @@
<string name="recent_conversations" msgid="8531874684782574622">"Акыркы сүйлөшүүлөр"</string>
<string name="days_timestamp" msgid="5821854736213214331">"<xliff:g id="DURATION">%1$s</xliff:g> күн мурун"</string>
<string name="one_week_timestamp" msgid="4925600765473875590">"1 апта мурун"</string>
- <string name="two_weeks_timestamp" msgid="9111801081871962155">"2 апта мурда"</string>
+ <string name="two_weeks_timestamp" msgid="9111801081871962155">"2 апта мурун"</string>
<string name="over_one_week_timestamp" msgid="3770560704420807142">"1 аптадан ашык мурда"</string>
<string name="over_two_weeks_timestamp" msgid="6300507859007874050">"2 аптадан ашык мурда"</string>
<string name="birthday_status" msgid="2596961629465396761">"Туулган күн"</string>
@@ -890,7 +884,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"Мазмун бир аздан кийин көрүнөт"</string>
<string name="missed_call" msgid="4228016077700161689">"Жооп берилбеген чалуу"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"Акыркы билдирүүлөрдү, жооп берилбеген чалууларды жана статустардын жаңырганын көрөсүз"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"Соңку билдирүүлөрдү, жооп берилбеген чалууларды жана статустардын жаңырганын көрөсүз"</string>
<string name="people_tile_title" msgid="6589377493334871272">"Сүйлөшүү"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"\"Тынчымды алба\" режими тындырды"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ce978d6..0159d12a 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ກະລຸນາລອງຖ່າຍຮູບໜ້າຈໍອີກຄັ້ງ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ບໍ່ສາມາດບັນທຶກຮູບໜ້າຈໍໄດ້"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຖ່າຍຮູບໜ້າຈໍ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ແກ້ໄຂ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ແກ້ໄຂຮູບໜ້າຈໍ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ແບ່ງປັນຮູບໜ້າຈໍ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ອຸປະກອນນີ້ແມ່ນສະໜອງໃຫ້ໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ ແລະ ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ແລະ ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ອົງກອນຂອງທ່ານສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານໄດ້"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານໄດ້"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ການເຄື່ອນໄຫວເຄືອຂ່າຍໂປຣໄຟລ໌ບ່ອນເຮັດວຽກແມ່ນສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານເຫັນໄດ້"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ເຄືອຂ່າຍອາດຖືກຕິດຕາມ"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ແອັບບ່ອນເຮັດວຽກຂອງທ່ານແມ່ນເຊື່ອມຕໍ່ຫາອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"ແອັບສ່ວນຕົວຂອງທ່ານເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ອຸປະກອນນີ້ແມ່ນສະໜອງໃຫ້ໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ການຈັດການອຸປະກອນ"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ມີອຳນາດໃບຮັບຮອງຕິດຕັ້ງຢູ່ໃນອຸປະກອນນີ້. ທຣາບຟິກເຄືອຂ່າຍທີ່ເຂົ້າລະຫັດໄວ້ຂອງທ່ານອາດຖືກຕິດຕາມ ຫຼື ແກ້ໄຂໄດ້."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ຜູ້ເບິ່ງແຍງຂອງທ່ານໄດ້ເປີດໃຊ້ການບັນທຶກເຄືອຂ່າຍໄວ້, ເຊິ່ງຈະຕິດຕາມທຣາບຟິກໃນອຸປະກອນຂອງທ່ານ."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ຜູ້ເບິ່ງແຍງຂອງທ່ານໄດ້ເປີດໃຊ້ການບັນທຶກເຄືອຂ່າຍໄວ້, ເຊິ່ງຈະຕິດຕາມທຣາບຟິກໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ ແຕ່ຈະບໍ່ຕິດຕາມໃນໂປຣໄຟລ໌ສ່ວນຕົວຂອງທ່ານ."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>. ການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ ແລະ ຂໍ້ມູນການນຳໃຊ້, ແມ່ນສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີເຫັນໄດ້."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ອຸປະກອນນີ້ເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ແລະ <xliff:g id="VPN_APP_1">%2$s</xliff:g>. ການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ ແລະ ຂໍ້ມູນການນຳໃຊ້, ແມ່ນສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີເຫັນໄດ້."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ແອັບບ່ອນເຮັດວຽກຂອງທ່ານເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>. ການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານໃນແອັບບ່ອນເຮັດວຽກ, ຮວມທັງອີເມວ ແລະ ຂໍ້ມູນການນຳໃຊ້, ແມ່ນສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີ ແລະ ຜູ້ໃຫ້ບໍລິການ VPN ຂອງທ່ານເຫັນໄດ້."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"ແອັບສ່ວນຕົວຂອງທ່ານເຊື່ອມຕໍ່ອິນເຕີເນັດຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>. ການເຄື່ອນໄຫວເຄືອຂ່າຍຂອງທ່ານ, ຮວມທັງອີເມວ ແລະ ຂໍ້ມູນການນຳໃຊ້, ແມ່ນສະແດງໃຫ້ຜູ້ໃຫ້ບໍລິການ VPN ຂອງທ່ານເຫັນໄດ້."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"ເປີດການຕັ້ງຄ່າ VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ. ພໍ່ແມ່ຂອງທ່ານສາມາດເບິ່ງ ແລະ ຈັດການຂໍ້ມູນໄດ້ ເຊັ່ນ: ແອັບທີ່ທ່ານໃຊ້, ສະຖານທີ່ ແລະ ເວລາໜ້າຈໍຂອງທ່ານ."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ເປີດໃຊ້ເມື່ອແບັດເຕີຣີໜ້າຈະໃກ້ໝົດ"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ບໍ່, ຂອບໃຈ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ແອັບພລິເຄຊັນກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%s</xliff:g> ຂອງທ່ານ."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ແລະ "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ຊື່ການອອກອາກາດ"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"ລະຫັດຜ່ານ"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ບັນທຶກ"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ກໍາລັງເລີ່ມ…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ບໍ່ສາມາດອອກອາກາດໄດ້"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 8177a90..99de00a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Pabandykite padaryti ekrano kopiją dar kartą"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekrano kopijos išsaugoti nepavyko"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Redaguoti"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Redaguoti ekrano kopiją"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Bendrinti ekrano kopiją"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šis įrenginys priklauso jūsų organizacijai ir ji gali stebėti tinklo srautą"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir ji gali stebėti tinklo srautą"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Šį įrenginį teikia „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Šis įrenginys priklauso jūsų organizacijai ir yra prijungtas prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir yra prijungtas prie interneto naudojant „<xliff:g id="VPN_APP">%2$s</xliff:g>“"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Šis įrenginys priklauso jūsų organizacijai"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Šis įrenginys priklauso jūsų organizacijai ir yra prijungtas prie interneto naudojant VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ ir yra prijungtas prie interneto naudojant VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jūsų organizacija darbo profilyje gali stebėti tinklo srautą"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"„<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>“ darbo profilyje gali stebėti tinklo srautą"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Darbo profilio tinklo veiklą mato jūsų IT administratorius"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Tinklas gali būti stebimas"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Šis įrenginys prijungtas prie interneto naudojant VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Jūsų darbo programos prijungtos prie interneto naudojant <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Jūsų asmeninės programos prijungtos prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Šis įrenginys prijungtas prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Šį įrenginį teikia „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Įrenginio tvarkymas"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Šiame įrenginyje įdiegtas sertifikato įgaliojimas. Jūsų saugaus tinklo srautas gali būti stebimas arba keičiamas."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratorius įjungė tinklo duomenų įrašymą į žurnalą. Įjungus šią funkciją stebimas srautas jūsų įrenginyje."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratorius įjungė tinklo duomenų įrašymą į žurnalą. Įjungus šią funkciją stebimas srautas jūsų darbo, bet ne asmeniniame profilyje."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Šis įrenginys prijungtas prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“. Jūsų tinklo veikla, įskaitant el. laiškus ir naršymo duomenis, matoma jūsų IT administratoriui."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Šis įrenginys prijungtas prie interneto naudojant „<xliff:g id="VPN_APP_0">%1$s</xliff:g>“ ir „<xliff:g id="VPN_APP_1">%2$s</xliff:g>“. Jūsų tinklo veikla, įskaitant el. laiškus ir naršymo duomenis, matoma jūsų IT administratoriui."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Jūsų darbo programos prijungtos prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“. Jūsų tinklo veikla darbo programose, įskaitant el. laiškus ir naršymo duomenis, matoma jūsų IT administratoriui ir VPN teikėjui."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Jūsų asmeninės programos prijungtos prie interneto naudojant „<xliff:g id="VPN_APP">%1$s</xliff:g>“. Jūsų tinklo veikla, įskaitant el. laiškus ir naršymo duomenis, matoma jūsų VPN teikėjui."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Atidaryti VPN nustatymus"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Šį įrenginį tvarko vienas iš tavo tėvų. Jis gali peržiūrėti ir tvarkyti informaciją, pvz., tavo naudojamas programas, vietovę ir įrenginio naudojimo laiką."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Įjunkite, jei akumuliatorius gali greitai išsekti"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, ačiū"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Pat. „SysUI“ krūvą"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ir "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Transliacijos pavadinimas"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Slaptažodis"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Išsaugoti"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Pradedama…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nepavyko transliuoti"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 56387ff..ed54621 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Mēģiniet izveidot jaunu ekrānuzņēmumu."</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nevar saglabāt ekrānuzņēmumu"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Rediģēt"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Rediģēt ekrānuzņēmumu"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Kopīgot ekrānuzņēmumu"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šī ierīce pieder jūsu organizācijai, un jūsu organizācija var uzraudzīt tīkla datplūsmu."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Šī ierīce pieder organizācijai<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, un šī organizācija var uzraudzīt tīkla datplūsmu."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Šo ierīci nodrošina <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Šī ierīce pieder jūsu organizācijai; tajā izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>; tajā ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Šī ierīce pieder jūsu organizācijai."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Šī ierīce pieder jūsu organizācijai; tajā izveidots savienojums ar internetu, izmantojot VPN tīklus."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>; tajā ir izveidots savienojums ar internetu, izmantojot VPN tīklus."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Jūsu organizācija var uzraudzīt jūsu darba profila tīkla datplūsmu."</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> var uzraudzīt jūsu profila tīkla datplūsmu."</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT administrators var skatīt tīklā veiktās darbības, kurām izmantojat darba profilu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Var tikt pārraudzītas tīklā veiktās darbības."</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Šajā ierīcē ir izveidots savienojums ar internetu, izmantojot VPN tīklus."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Jūsu darba lietotnēs ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Jūsu personīgajās lietotnēs ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Šajā ierīcē ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Šo ierīci nodrošina <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ierīces pārvaldība"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Šajā ierīcē ir instalēts sertifikāts. Drošā tīkla datplūsma var tikt uzraudzīta."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrators ieslēdza tīkla reģistrēšanu, kuru izmanto, lai pārraudzītu datplūsmu jūsu ierīcē."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrators ir ieslēdzis tīkla reģistrēšanu, kuru izmanto, lai pārraudzītu datplūsmu jūsu darba profilā, bet ne personīgajā profilā."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Šajā ierīcē ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>. IT administratoram ir redzamas jūsu tīklā veiktās darbības, tostarp e-pasta ziņojumi un pārlūkošanas dati."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Šajā ierīcē ir izveidots savienojums ar internetu, izmantojot lietotnes <xliff:g id="VPN_APP_0">%1$s</xliff:g> un <xliff:g id="VPN_APP_1">%2$s</xliff:g>. IT administratoram ir redzamas jūsu tīklā veiktās darbības, tostarp e-pasta ziņojumi un pārlūkošanas dati."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Jūsu darba lietotnēs ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>. IT administratoram un VPN nodrošinātājam ir redzamas jūsu tīklā veiktās darbības darba lietotnēs, tostarp e-pasta ziņojumi un pārlūkošanas dati."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Jūsu personīgajās lietotnēs ir izveidots savienojums ar internetu, izmantojot lietotni <xliff:g id="VPN_APP">%1$s</xliff:g>. VPN nodrošinātājam ir redzamas jūsu tīklā veiktās darbības, tostarp e-pasta ziņojumi un pārlūkošanas dati."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Atvērt VPN iestatījumus"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Šo ierīci pārvalda viens no jūsu vecākiem. Vecāki var skatīt un pārvaldīt tādu informāciju kā jūsu izmantotās lietotnes, atrašanās vieta un izmantošanas ilgums."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ieslēgt, ja akumulators var izlādēties"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nē, paldies"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Lietojumprogrammas izmanto šādas funkcijas: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" un "</string>
@@ -861,9 +853,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Apraides nosaukums"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Parole"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saglabāt"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Notiek palaišana…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nevar apraidīt"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5af0199..92fef05 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Повторно обидете се да направите слика од екранот"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Не може да се зачува слика од екранот"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликацијата или вашата организација не дозволува снимање слики од екранот"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Изменете ја сликата од екранот"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Споделете слика од екранот"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> го обезбедува уредов"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Уредов е во сопственост на вашата организација и е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е поврзан на интернет преку <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Уредов е во сопственост на организацијата"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Уредов е во сопственост на вашата организација и е поврзан на интернет преку VPN."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> и е поврзан на интернет преку VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Вашата организација може да го следи мрежниот сообраќај на вашиот работен профил"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> може да го следи мрежниот сообраќај на вашиот работен профил"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Мрежната активност на работниот профил е видлива за IT-администраторот"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мрежата можеби се следи"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Уредов е поврзан на интернет преку VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Вашите работни апликации се поврзани на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Вашите лични апликации се поврзани на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Уредов е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> го обезбедува уредов"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управување со уреди"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На уредов е инсталиран авторитет за сертификат. Вашиот безбеден мрежен сообраќај можно е да се следи или изменува."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Вашиот администратор вклучил евиденција на мрежата, што подразбира следење на сообраќајот на вашиот уред."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Вашиот администратор вклучил мрежна евиденција, што подразбира следење на сообраќајот во работниот, но не и во личниот профил."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Уредов е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, вклучително е-пораките и податоците од прелистување, е видлива за вашиот IT-администратор."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Уредот е поврзан на интернет преку <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Вашата мрежна активност во работните апликации, вклучително е-пораките и податоците од прелистување, е видлива за вашиот IT-администратор."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Вашите работни апликации се поврзани на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, вклучително е-пораките и податоците од прелистување, е видлива за вашиот IT-администратор и давател на услуги за VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Вашите лични апликации се поврзани на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, вклучително е-пораките и податоците од прелистување, е видлива за вашиот давател на услуги за VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Отворете „Поставки за VPN“"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Родителот управува со уредов. Родителот може да прегледува и управува со податоците, како што се апликациите што ги користиш, твојата локација и времето поминато на уредот."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Вклучи ако е веројатно дека батеријата ќе се испразни"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Не, фала"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Извади SysUI-слика"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликациите користат <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Назив на емитувањето"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Лозинка"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Зачувај"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Се стартува…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не може да се емитува"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index fa24185..f954262 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ വീണ്ടും ശ്രമിക്കുക"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കാനാകുന്നില്ല"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"എഡിറ്റ് ചെയ്യുക"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"സ്ക്രീൻഷോട്ട് എഡിറ്റ് ചെയ്യുക"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"സ്ക്രീൻഷോട്ട് പങ്കിടുക"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> നൽകിയ ഉപകരണമാണിത്"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്, <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇത് ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്, <xliff:g id="VPN_APP">%2$s</xliff:g> വഴി ഇത് ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്, VPN-കൾ വഴി ഇത് ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്, VPN-കൾ വഴി ഇത് ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിലെ നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കാൻ നിങ്ങളുടെ സ്ഥാപനത്തിന് കഴിഞ്ഞേക്കാം"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിലെ നെറ്റ്വർക്ക് ട്രാഫിക്ക് <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> നിരീക്ഷിച്ചേക്കാം"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ഔദ്യോഗിക പ്രൊഫൈലിലെ നെറ്റ്വര്ക്ക് ആക്റ്റിവിറ്റി ഐടി അഡ്മിന് കാണാനാകും"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"നെറ്റ്വർക്ക് നിരീക്ഷിക്കപ്പെടാം"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ഈ ഉപകരണം VPN-കൾ വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ഈ ഉപകരണം <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> നൽകിയ ഉപകരണമാണിത്"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ഉപകരണ മാനേജ്മെന്റ്"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"നിങ്ങളുടെ അഡ്മിൻ, നെറ്റ്വർക്ക് ലോഗിംഗ് ഓണാക്കിയിട്ടുണ്ട്, ഇതിന് നിങ്ങളുടെ ഉപകരണത്തിലെ ട്രാഫിക്ക് നിരീക്ഷിക്കാൻ കഴിയും."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"നിങ്ങളുടെ അഡ്മിൻ നെറ്റ്വർക്ക് ലോഗിംഗ് ഓണാക്കി, ഇത് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിലെ ട്രാഫിക് നിരീക്ഷിക്കുന്നു എന്നാൽ വ്യക്തിപരമായ പ്രൊഫൈലിലെ ട്രാഫിക് നിരീക്ഷിക്കുന്നില്ല."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ഈ ഉപകരണം <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്മിന് ദൃശ്യമാകും."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ഈ ഉപകരണം <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നിവയിലൂടെ ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്മിന് ദൃശ്യമാകും."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള, ഔദ്യോഗിക ആപ്പുകളിലെ നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്മിനും VPN ദാതാവിനും ദൃശ്യമാകും."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്റ്റ് ചെയ്തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിങ്ങളുടെ VPN ദാതാവിന് ദൃശ്യമാകും."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" 5"</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ക്രമീകരണം തുറക്കുക"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാനും നിയന്ത്രിക്കാനുമാകും."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"വേണ്ട"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ആപ്പുകൾ നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" കൂടാതെ "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"സംരക്ഷിക്കുക"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"ആരംഭിക്കുന്നു…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ബ്രോഡ്കാസ്റ്റ് ചെയ്യാനാകുന്നില്ല"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0bb6ecb..3eaf5f1 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Дэлгэцийн зургийг дахин дарж үзнэ үү"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Дэлгэцийн агшныг хадгалах боломжгүй"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Таны апп, байгууллагад дэлгэцийн зураг авахыг зөвшөөрдөггүй"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Засах"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Дэлгэцийн агшныг засах"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Дэлгэцийн агшныг хуваалцах"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-с нийлүүлдэг"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг бөгөөд <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг бөгөөд <xliff:g id="VPN_APP">%2$s</xliff:g>-р интернэтэд холбогдсон байна"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг бөгөөд VPN-р интернэтэд холбогдсон байна"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>-д харьяалагддаг бөгөөд VPN-р интернэтэд холбогдсон байна"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Таны байгууллага таны ажлын профайлын сүлжээний ачааллыг хянадаг"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> таны ажлын профайлын сүлжээний ачааллыг хянадаг"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Таны IT админд ажлын профайлын сүлжээний үйл ажиллагаа харагдана"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Сүлжээг хянаж байж болзошгүй"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Энэ төхөөрөмж VPN-р интернэтэд холбогдсон байна"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Таны ажлын аппууд <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Таны хувийн аппууд <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Энэ төхөөрөмж <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-с нийлүүлдэг"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Төхөөрөмжийн удирдлага"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Сертификатын зөвшөөрлийг энэ төхөөрөмжид суулгасан байна. Таны аюулгүй сүлжээний ачааллыг өөрчлөх эсвэл хянах боломжтой."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Таны админ төхөөрөмжийн ачааллыг хянадаг сүлжээний логийг асаасан байна."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Таны админ ажлын профайлын тань ачааллыг хянадаг сүлжээний логийг асаасан бөгөөд энэ нь хувийн профайлын ачааллыг хянахгүй."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Энэ төхөөрөмж <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна. Таны имэйл болон интернэтээр үзсэн өгөгдөл зэрэг сүлжээний үйл ажиллагаа таны IT админд харагдана."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Энэ төхөөрөмж <xliff:g id="VPN_APP_0">%1$s</xliff:g> болон <xliff:g id="VPN_APP_1">%2$s</xliff:g>-р интернэтэд холбогдсон байна. Таны имэйл болон интернэтээр үзсэн өгөгдөл зэрэг сүлжээний үйл ажиллагаа таны IT админд харагдана."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Таны ажлын аппууд <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна. Таны имэйл болон интернэтээр үзсэн өгөгдөл зэрэг ажлын аппууд дахь сүлжээний үйл ажиллагаа таны IT админ болон VPN-н үйлчилгээ үзүүлэгчид харагдана."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Таны хувийн аппууд <xliff:g id="VPN_APP">%1$s</xliff:g>-р интернэтэд холбогдсон байна. Таны имэйл болон интернэтээр үзсэн өгөгдөл зэрэг сүлжээний үйл ажиллагаа таны VPN-н үйлчилгээ үзүүлэгчид харагдана."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN тохиргоог нээх"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Энэ төхөөрөмжийг таны эцэг эх удирддаг. Таны эцэг эх таны хэрэглэдэг апп, байршил, дэлгэцийн цаг зэрэг мэдээллийг харж, удирдах боломжтой."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Батарей дуусах гэж байгаа үед асаана уу"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Үгүй, баярлалаа"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" болон "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Хадгалах"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"Эхлүүлж байна…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Нэвтрүүлэх боломжгүй"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 3f1d07d..1ddf2c7 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रीनशॉट पुन्हा घेण्याचा प्रयत्न करा"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"स्क्रीनशॉट सेव्ह करू शकत नाही"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"अॅप किंवा आपल्या संस्थेद्वारे स्क्रीनशॉट घेण्याची अनुमती नाही"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"संपादित करा"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रीनशॉट संपादित करा"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेअर करा"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"तुमच्या संस्थेकडे या डिव्हाइसची मालकी आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> च्या मालकीचे आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारे पुरवले गेले आहे"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"हे डिव्हाइस तुमच्या संस्थेचे आहे आणि ते <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे आणि ते <xliff:g id="VPN_APP">%2$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"हे डिव्हाइस तुमच्या संस्थेचे आहे आणि ते VPNs द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> चे आहे आणि ते VPNs द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"तुमची संस्था आपल्या कार्य प्रोफाइलमधील नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> आपल्या कार्य प्रोफाइलमधील नेटवर्क रहदारीचे परीक्षण करू शकते"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"तुमच्या IT ॲडमिनला कार्य प्रोफाइलची नेटवर्क अॅक्टिव्हिटी दृश्यमान आहे"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"हे डिव्हाइस VPNs द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"तुमची कार्य ॲप्स <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेली आहेत"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"तुमची वैयक्तिक ॲप्स <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेली आहेत"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"हे डिव्हाइस <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेले आहे"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारे पुरवले गेले आहे"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिव्हाइस व्यवस्थापन"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपल्या प्रशासकाने नेटवर्क लॉगिंग सुरू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे परीक्षण करते."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"तुमच्या ॲडमिनने नेटवर्क लॉग इन सुरू केले आहे, जे तुमच्या कार्य प्रोफाइलमधील रहदारीचे निरीक्षण करत असले तरी तुमच्या वैयक्तिक प्रोफाइलमधील रहदारीचे निरीक्षण करत नाही."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"हे डिव्हाइस <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेले आहे. ईमेल आणि ब्राउझिंग डेटासोबतच, तुमची नेटवर्क अॅक्टिव्हिटी तुमच्या आयटी ॲडमिनला दृश्यमान आहे."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"हे डिव्हाइस <xliff:g id="VPN_APP_0">%1$s</xliff:g> आणि <xliff:g id="VPN_APP_1">%2$s</xliff:g> यांद्वारे इंटरनेटशी कनेक्ट केलेले आहे. ईमेल आणि ब्राउझिंग डेटासोबतच, तुमची नेटवर्क अॅक्टिव्हिटी तुमच्या आयटी ॲडमिनला दृश्यमान आहे."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"तुमची कार्य ॲप्स <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेली आहेत. ईमेल आणि ब्राउझिंग डेटासोबतच, तुमच्या कार्य ॲप्समधील नेटवर्क अॅक्टिव्हिटी तुमच्या आयटी ॲडमिन आणि VPN पुरवठादाराला दृश्यमान आहे."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"तुमची वैयक्तिक ॲप्स <xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे इंटरनेटशी कनेक्ट केलेली आहेत. ईमेल आणि ब्राउझिंग डेटासोबतच, तुमची नेटवर्क अॅक्टिव्हिटी तुमच्या VPN पुरवठादाराला दृश्यमान आहे."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN सेटिंग्ज उघडा"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे. तुम्ही वापरत असलेली ॲप्स, तुमचे स्थान आणि तुमचा स्क्रीन वेळ यांसारखी माहिती तुमचे पालक पाहू आणि व्यवस्थापित करू शकतात."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"बॅटरी संपण्याची शक्यता असल्यास सुरू करा"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"नाही नको"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI हीप डंप करा"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ॲप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" आणि "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेव्ह करा"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"सुरू करत आहे…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट करू शकत नाही"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 665e0e6..99266cf 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Cuba ambil tangkapan skrin sekali lagi"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Tidak dapat menyimpan tangkapan skrin"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Pengambilan tangkapan skrin tidak dibenarkan oleh apl atau organisasi anda"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edit tangkapan skrin"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Kongsi tangkapan skrin"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi anda memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Peranti ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Peranti ini milik organisasi anda dan disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Peranti ini milik organisasi anda"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Peranti ini milik organisasi anda dan disambungkan ke Internet melalui VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dan disambungkan kepada Internet melalui VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasi anda mungkin memantau trafik rangkaian dalam profil kerja anda"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mungkin memantau trafik rangkaian dalam profil kerja anda"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktiviti rangkaian profil kerja boleh dilihat oleh pentadbir IT anda"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Rangkaian mungkin dipantau"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Peranti ini disambungkan kepada Internet melalui VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Apl kerja anda disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Apl peribadi anda disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Peranti ini disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Peranti ini disediakan oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pengurusan peranti"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sijil kuasa dipasang pada peranti ini. Trafik rangkaian selamat anda mungkin dipantau atau diubah suai."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Pentadbir anda telah menghidupkan pengelogan rangkaian yang memantau trafik pada peranti anda."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Pentadbir anda telah menghidupkan pengelogan rangkaian yang memantau trafik dalam profil kerja anda tetapi bukan dalam profil peribadi anda."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Peranti ini disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviti rangkaian anda, termasuk e-mel dan data semakan imbas boleh dilihat oleh pentadbir IT anda."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Peranti ini disambungkan kepada Internet melalui <xliff:g id="VPN_APP_0">%1$s</xliff:g> dan <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Aktiviti rangkaian anda, termasuk e-mel dan data semakan imbas boleh dilihat oleh pentadbir IT anda."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Apl kerja anda disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviti rangkaian anda dalam apl kerja, termasuk e-mel dan data semakan imbas boleh dilihat oleh pentadbir IT dan pembekal VPN anda."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Apl peribadi anda disambungkan kepada Internet melalui <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviti rangkaian anda, termasuk e-mel dan data semakan imbas boleh dilihat oleh pembekal VPN anda."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Buka tetapan VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Peranti ini diurus oleh ibu bapa anda. Ibu bapa anda dapat melihat dan mengurus maklumat seperti apl yang anda gunakan, lokasi dan masa skrin anda."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Hidupkan apabila bateri berkemungkinan habis"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Tidak perlu"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"DumpSys"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi sedang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> anda."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nama Siaran"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Kata Laluan"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Simpan"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Memulakan…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat disiarkan"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index c92a2dd..56c90a0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"မျက်နှာပြင်ပုံကို ထပ်ရိုက်ကြည့်ပါ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ဖန်သားပြင်ဓာတ်ပုံကို သိမ်း၍မရပါ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ကူးခြင်းကို ဤအက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"တည်းဖြတ်ရန်"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ဖန်သားပြင်ဓာတ်ပုံကို တည်းဖြတ်သည်"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ဖန်သားပြင်ဓာတ်ပုံကို မျှဝေနိုင်သည်"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပံ့ပိုးထားသည်"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး <xliff:g id="VPN_APP">%2$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်သည်"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်ပြီး VPN များမှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> က ပိုင်ဆိုင်ပြီး VPN များမှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"သင်၏ အဖွဲ့အစည်းက သင့်အလုပ်ပရိုဖိုင်ရှိ ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်သည်"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> သည် သင်၏ အလုပ်ပရိုဖိုင်ရှိ ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"အလုပ်ပရိုဖိုင်ကွန်ရက် လုပ်ဆောင်ချက်ကို သင့် IT စီမံခန့်ခွဲသူက မြင်နိုင်သည်"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ကွန်ရက်ကို စောင့်ကြည့်နိုင်ပါသည်"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ဤစက်သည် VPN များမှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"သင့်အလုပ်အက်ပ်များကို <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"သင့်ကိုယ်ရေးသုံးအက်ပ်များကို <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ဤစက်သည် <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပံ့ပိုးထားသည်"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"စက်ပစ္စည်း စီမံခန့်ခွဲမှု"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ဤစက်ပစ္စည်းတွင် စီမံခန့်ခွဲမှုဆိုင်ရာ အသိအမှတ်ပြုလက်မှတ်ကို ထည့်သွင်းထားပါသည်။ လုံခြုံမှုရှိသော ကွန်ရက်ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်ခြင်း သို့မဟုတ် ပြုပြင်ခြင်းများ ပြုလုပ်နိုင်ပါသည်။"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"စက်ပစ္စည်းပေါ်ရှိ ဒေတာစီးဆင်းမှုများကို စောင့်ကြည့်နိုင်သည့် ကွန်ရက်မှတ်တမ်းတင်ခြင်းစနစ်ကို သင်၏ စီမံခန့်ခွဲသူက ဖွင့်ထားပါသည်။"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"သင်၏စီမံခန့်ခွဲသူက ကွန်ရက်မှတ်တမ်းတင်ခြင်းကို ဖွင့်လိုက်သည်။ ၎င်းသည် သင့်အလုပ်ပရိုဖိုင်ရှိ ဒေတာစီးဆင်းမှုကို စောင့်ကြည့်သော်လည်း ကိုယ်ပိုင်ပရိုဖိုင်တွင် မစောင့်ကြည့်ပါ။"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ဤစက်သည် <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်။ အီးမေးလ်များနှင့် ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာများ အပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်များကို IT စီမံခန့်ခွဲသူက မြင်ရသည်။"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ဤစက်သည် <xliff:g id="VPN_APP_0">%1$s</xliff:g> နှင့် <xliff:g id="VPN_APP_1">%2$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်။ အီးမေးလ်များနှင့် ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာများ အပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်များကို IT စီမံခန့်ခွဲသူက မြင်ရသည်။"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"သင့်အလုပ်အက်ပ်များကို <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်။ အီးမေးလ်များနှင့် ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာများ အပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်များကို IT စီမံခန့်ခွဲသူနှင့် VPN ပံ့ပိုးသူက မြင်ရသည်။"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"သင့်ကိုယ်ရေးသုံးအက်ပ်များကို <xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့် အင်တာနက်ချိတ်ထားသည်။ အီးမေးလ်များနှင့် ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာများ အပါအဝင် သင့်ကွန်ရက်လုပ်ဆောင်ချက်များကို VPN ပံ့ပိုးသူက မြင်ရသည်။"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ဆက်တင်များကို ဖွင့်ရန်"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်။ သင့်မိဘက သင်သုံးသောအက်ပ်များ၊ သင်၏တည်နေရာနှင့် အသုံးပြုချိန် ကဲ့သို့သော အချက်အလက်များကို မြင်နိုင်ပြီး စီမံခန့်ခွဲနိုင်သည်။"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ဘက်ထရီကုန်ခါနီးတွင် ဖွင့်ပါ"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"မလိုပါ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"အပလီကေးရှင်းများက သင်၏ <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"၊ "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" နှင့် "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ထုတ်လွှင့်မှုအမည်"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"စကားဝှက်"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"သိမ်းရန်"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"စတင်နေသည်…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ထုတ်လွှင့်၍ မရပါ"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 94b9b3a..d8915c4 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermdump på nytt"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermdumpen"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> eier denne enheten og kan overvåke nettverkstrafikken"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Denne enheten leveres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Denne enheten tilhører organisasjonen din og er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til internett via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Denne enheten tilhører organisasjonen din"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Denne enheten tilhører organisasjonen din og er koblet til internett via VPN-er"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> og er koblet til internett via VPN-er"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisasjonen din kan overvåke nettverkstrafikken i jobbprofilen din"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan overvåke nettverkstrafikken i jobbprofilen din"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT-administratoren kan se nettverksaktivitet i jobbprofilen din"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Nettverket kan bli overvåket"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Denne enheten er koblet til internett via VPN-er"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Jobbappene dine er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"De personlige appene dine er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Denne enheten er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Denne enheten leveres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetsadministrasjon"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"En sertifiseringsinstans er installert på denne enheten. Den sikre nettverkstrafikken din kan overvåkes eller endres."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratoren din har slått på loggføring av nettverk, som overvåker trafikken på enheten din."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratoren din har slått på loggføring av nettverk, som overvåker trafikken i jobbprofilen din, men ikke i den personlige profilen din."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Denne enheten er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>. Nettverksaktiviteten din, inkludert e-poster og nettlesingsdata, er synlig for IT-administratoren din."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Denne enheten er koblet til internett via <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Nettverksaktiviteten din, inkludert e-poster og nettlesingsdata, er synlig for IT-administratoren din."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Jobbappene dine er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>. Nettverksaktiviteten din i jobbapper, inkludert e-poster og nettlesingsdata, er synlige for IT-administratoren og VPN-leverandøren din."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"De personlige appene dine er koblet til internett via <xliff:g id="VPN_APP">%1$s</xliff:g>. Nettverksaktiviteten din, inkludert e-poster og nettlesingsdata, er synlig for VPN-leverandøren din."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Åpne VPN-innstillingene"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Denne enheten administreres av forelderen din. Forelderen din kan se og administrere informasjon, for eksempel appene du bruker, posisjonen din og skjermtiden din."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Slå på når det er sannsynlig at du går tom for batteri"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nei takk"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apper bruker <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Kringkastingsnavn"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Passord"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Lagre"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starter …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan ikke kringkaste"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 07cb7d4..7843645 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त एप वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"सम्पादन गर्नुहोस्"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रिनसट सम्पादन गर्नुहोस्"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रिनसट सेयर गर्नुहोस्"</string>
@@ -376,8 +378,7 @@
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"तपाईंका IT एड्मिन कार्य प्रोफाइलमा हुने नेटवर्कसम्बन्धी क्रियाकलाप देख्न सक्नुहुन्छ"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"नेटवर्कको अनुगमन हुनसक्छ"</string>
<string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"यो डिभाइस VPN हरूमार्फत इन्टरनेटमा कनेक्ट गरिएको छ"</string>
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"तपाईंका कामसम्बन्धी एपहरू <xliff:g id="VPN_APP">%1$s</xliff:g> मार्फत इन्टरनेटमा कनेक्ट गरिएका छन्।"</string>
<string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"तपाईंका व्यक्तिगत एपहरू <xliff:g id="VPN_APP">%1$s</xliff:g> मार्फत इन्टरनेटमा कनेक्ट गरिएका छन्"</string>
<string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"यो डिभाइस <xliff:g id="VPN_APP">%1$s</xliff:g> मार्फत इन्टरनेटमा कनेक्ट गरिएको छ"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ले यो डिभाइस उपलब्ध गराएको हो"</string>
@@ -719,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ब्याट्री सकिने सम्भावना भएमा अन गर्नुहोस्"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"पर्दैन धन्यवाद"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"एपहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" र "</string>
@@ -846,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"सेभ गर्नुहोस्"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"सुरु गरिँदै छ…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"प्रसारण गर्न सकिएन"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 82f3be3..fec927c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Probeer opnieuw een screenshot te maken"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan screenshot niet opslaan"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Bewerken"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bewerken"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot delen"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft verbinding met internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dit apparaat is eigendom van je organisatie"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Dit apparaat is eigendom van je organisatie en heeft verbinding met internet via VPN\'s"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> en heeft verbinding met internet via VPN\'s"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Je organisatie kan het netwerkverkeer in je werkprofiel bijhouden"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan het netwerkverkeer in je werkprofiel bijhouden"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"De netwerkactiviteit van je werkprofiel is zichtbaar voor je IT-beheerder"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Netwerk kan worden bijgehouden"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Dit apparaat heeft verbinding met internet via VPN\'s"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Je werk-apps hebben verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Je persoonlijke apps hebben verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Dit apparaat wordt geleverd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Apparaatbeheer"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Er is een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Je beheerder heeft de netwerkregistratie aangezet, waarmee het verkeer op je apparaat wordt gecontroleerd."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Je beheerder heeft netwerkregistratie aangezet. Hiermee wordt verkeer in je werkprofiel bijgehouden, maar niet in je persoonlijke profiel."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> en <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Je werk-apps hebben verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit in werk-apps, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder en VPN-provider."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Je persoonlijke apps hebben verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor je VPN-provider."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN-instellingen openen"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dit apparaat wordt beheerd door je ouder. Je ouder kan informatie bekijken en beheren, zoals de apps die je gebruikt, je locatie en je schermtijd."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aanzetten als de batterij waarschijnlijk leeg raakt"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nee, bedankt"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps gebruiken je <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Naam van uitzending"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Wachtwoord"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Opslaan"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Starten…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan niet uitzenden"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 7c95348..fb2d2e4 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ପୁଣିଥରେ ସ୍କ୍ରୀନ୍ଶଟ୍ ନେବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ସ୍କ୍ରିନସଟକୁ ସେଭ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ଆପ୍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ୍ କରନ୍ତୁ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ୍ କରନ୍ତୁ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ଏହି ଡିଭାଇସର ମାଲିକାନା ଆପଣଙ୍କ ସଂସ୍ଥା ପାଖରେ ଅଛି ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକର ନିରୀକ୍ଷଣ କରିପାରେ"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକକୁ ନିରୀକ୍ଷଣ କରିପାରେ"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ଏହି ଡିଭାଇସ୍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ ଏବଂ ଏହା <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା <xliff:g id="VPN_APP">%2$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ ଏବଂ ଏହା VPNଗୁଡ଼ିକ ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>ର ଅଟେ ଏବଂ ଏହା VPNଗୁଡ଼ିକ ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲରେ ଆପଣଙ୍କ ସଂସ୍ଥା ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରିପାରନ୍ତି"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲରେ ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରିପାରନ୍ତି"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯିବ"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ନେଟୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ଏହି ଡିଭାଇସ VPNଗୁଡ଼ିକ ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଆପ୍ସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ଏହି ଡିଭାଇସ୍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପ୍ରଦାନ କରାଯାଇଛି"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ଡିଭାଇସ୍ ପରିଚାଳନା"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ଏହି ଡିଭାଇସରେ ଏକ ସର୍ଟିଫିକେଟ୍ ଅଥରିଟି ଇନଷ୍ଟଲ୍ କରାଯାଇଛି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ଆପଣଙ୍କ ଆଡମିନ୍ ନେଟୱର୍କ ଲଗଇନ୍ କରିବା ଅନ୍ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ଡିଭାଇସରେ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରେ।"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ଆପଣଙ୍କ ଆଡମିନ୍ ନେଟୱାର୍କ ଲଗିଂ ଚାଲୁ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲରେ ଟ୍ରାଫିକ୍ ନିରୀକ୍ଷଣ କରେ କିନ୍ତୁ ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲରେ ନୁହେଁ।"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ଆପଣଙ୍କ ଡିଭାଇସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ଏବଂ <xliff:g id="VPN_APP_1">%2$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ୱାର୍କ ଆପ୍ସରେ ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନ ଏବଂ VPN ପ୍ରଦାନକାରୀଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଆପ୍ସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର VPN ପ୍ରଦାନକାରୀଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ସେଟିଂସ୍ ଖୋଲନ୍ତୁ"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ। ଆପଣଙ୍କ ବାପାମା ଆପଣ ବ୍ୟବହାର କରୁଥିବା ଆପ୍ସ, ଆପଣଙ୍କ ଲୋକେସନ୍ ଓ ସ୍କ୍ରିନ୍ ସମୟ ପରି ସୂଚନା ଦେଖିପାରିବେ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ବ୍ୟାଟେରୀ ସରିବାକୁ ଥିବା ସମୟରେ ଚାଲୁ କରନ୍ତୁ"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ନାହିଁ, ଥାଉ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ଆପ୍ଲିକେସନ୍ଗୁଡିକ ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ଏବଂ "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ବ୍ରଡକାଷ୍ଟର ନାମ"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"ପାସୱାର୍ଡ"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ସେଭ କରନ୍ତୁ"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ଆରମ୍ଭ ହେଉଛି…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ବ୍ରଡକାଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9a5c151..1b869d7 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੁਬਾਰਾ ਲੈ ਕੇ ਦੇਖੋ"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨੂੰ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ਸੰਪਾਦਨ ਕਰੋ"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਾਂਝਾ ਕਰੋ"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ <xliff:g id="VPN_APP">%2$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ VPN ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ ਅਤੇ VPN ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਖਾਈ ਦਿੰਦੀ ਹੈ"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ਨੈੱਟਵਰਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ਇਹ ਡੀਵਾਈਸ VPN ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ਤੁਹਾਡੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹਨ"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"ਤੁਹਾਡੀਆਂ ਨਿੱਜੀ ਐਪਾਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹਨ"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਮੁਹੱਈਆ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਪਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗ-ਇਨ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ ਪਰ ਤੁਹਾਡੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਨਹੀਂ।"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ। ਈਮੇਲਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਿੰਗ ਡਾਟੇ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="VPN_APP_1">%2$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹੈ। ਈਮੇਲਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਿੰਗ ਡਾਟੇ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ਤੁਹਾਡੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹਨ। ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਵਿੱਚ ਈਮੇਲਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਿੰਗ ਡਾਟੇ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਅਤੇ VPN ਪ੍ਰਦਾਨਕ ਨੂੰ ਦਿਸਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"ਤੁਹਾਡੀਆਂ ਨਿੱਜੀ ਐਪਾਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ ਇੰਟਰਨੈੱਟ ਨਾਲ ਕਨੈਕਟ ਹਨ। ਈਮੇਲਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਿੰਗ ਡਾਟੇ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਤੁਹਾਡੇ VPN ਪ੍ਰਦਾਨਕ ਨੂੰ ਦਿਸਦੀ ਹੈ।"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਤੁਹਾਡੀਆਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ, ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਅਤੇ ਤੁਹਾਡੇ ਸਕ੍ਰੀਨ ਸਮੇਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਦੇਖ ਅਤੇ ਉਸਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦੇ ਹਨ।"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"ਬੈਟਰੀ ਖਤਮ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ \'ਤੇ ਚਾਲੂ ਹੁੰਦਾ ਹੈ"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ਹੀਪ ਡੰਪ ਕਰੋ"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ਅਤੇ "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"ਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index aad11d6..687da89 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Spróbuj jeszcze raz wykonać zrzut ekranu"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nie można zapisać zrzutu ekranu."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Edytuj"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Edytuj zrzut ekranu"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Udostępnij zrzut ekranu"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"To urządzenie dostarcza organizacja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"To urządzenie należy do Twojej organizacji i jest połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"To urządzenie należy do organizacji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i jest połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"To urządzenie należy do Twojej organizacji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Właściciel tego urządzenia: <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"To urządzenie należy do Twojej organizacji i jest połączone z internetem za pomocą sieci VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"To urządzenie należy do organizacji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> i jest połączone z internetem za pomocą sieci VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Twoja organizacja może monitorować ruch w sieci w Twoim profilu służbowym"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> może monitorować ruch w sieci w Twoim profilu służbowym"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktywność w sieci w profilu służbowym jest widoczna dla administratora IT"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Sieć może być monitorowana"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"To urządzenie jest połączone z internetem za pomocą sieci VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Twoje aplikacje służbowe są połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Twoje aplikacje osobiste są połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"To urządzenie jest połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"To urządzenie dostarcza organizacja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Zarządzanie urządzeniami"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Urząd certyfikacji zainstalowany na tym urządzeniu. Twój zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim urządzeniu."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim profilu służbowym, ale nie na profilu osobistym."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"To urządzenie jest połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>. Twoja aktywność w sieci, w tym poczta e-mail i dane przeglądania, są widoczne dla administratora IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"To urządzenie jest połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Twoja aktywność w sieci, w tym poczta e-mail i dane przeglądania, są widoczne dla administratora IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Twoje aplikacje służbowe są połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>. Twoja aktywność w sieci w aplikacjach służbowych, w tym poczta e-mail i dane przeglądania, są widoczne dla administratora IT i firmy świadczącej usługi VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Twoje aplikacje osobiste są połączone z internetem za pomocą aplikacji <xliff:g id="VPN_APP">%1$s</xliff:g>. Twoja aktywność w sieci, w tym poczta e-mail i dane przeglądania, są widoczne dla firmy świadczącej usługi VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otwórz ustawienia VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tym urządzeniem zarządza Twój rodzic. Rodzic może zobaczyć różne informacje, np. o aplikacjach, których używasz, lokalizacji i czasie korzystania z urządzenia, a także zarządzać tymi danymi."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Oszczędzanie baterii włącza się, jeśli bateria jest prawie wyczerpana"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nie, dziękuję"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Zrzut stosu SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacje używają: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nazwa transmisji"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Hasło"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Zapisz"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Uruchamiam…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nie można przesyłać"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index f1f0532..17cac71 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não foi possível salvar a captura de tela"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Sua organização pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"A atividade de rede do perfil de trabalho fica visível para o administrador de TI"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado à Internet usando VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Uma autoridade de certificação foi instalada neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"O administrador ativou o registro de rede, que monitora o tráfego no seu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"O administrador ativou o registro de rede, que monitora o tráfego no seu perfil de trabalho, mas não no perfil pessoal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Seu dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede em apps de trabalho, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI e o provedor de VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configurações de VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ativada quando há possibilidade de a bateria acabar"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
@@ -855,16 +847,18 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome da transmissão"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Senha"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
- <string name="no_conversations_text" msgid="5354115541282395015">"Suas conversas recentes serão exibidas aqui"</string>
+ <string name="no_conversations_text" msgid="5354115541282395015">"Suas conversas recentes vão aparecer aqui"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string>
<string name="days_timestamp" msgid="5821854736213214331">"Há <xliff:g id="DURATION">%1$s</xliff:g> dias"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index ef9b01d..93cefa9 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Experimente voltar a efetuar a captura de ecrã."</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não é possível guardar a captura de ecrã."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"A app ou a sua entidade não permitem tirar capturas de ecrã"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de ecrã"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Partilhar captura de ecrã"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é proprietária deste dispositivo e pode monitorizar o tráfego de rede."</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo foi fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está ligado à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado à Internet através da app <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua entidade."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está ligado à Internet através de VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está ligado à Internet através de VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"A sua entidade pode monitorizar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorizar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"A atividade da rede do perfil de trabalho fica visível para o administrador de TI"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorizada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está ligado à Internet através de VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"As suas apps de trabalho estão ligadas à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"As suas apps pessoais estão ligadas à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está ligado à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo foi fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestão de dispositivos"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Está instalada uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"O gestor ativou os registos de rede, que monitorizam o tráfego no seu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"O seu administrador ativou os registos de rede, que monitorizam o tráfego no seu perfil de trabalho, mas não no seu perfil pessoal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está ligado à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>. A sua atividade de rede, incluindo dados de navegação e emails, está visível para o seu administrador de TI."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Este dispositivo está ligado à Internet através das apps <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. A sua atividade de rede, incluindo dados de navegação e emails, está visível para o seu administrador de TI."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"As suas apps de trabalho estão ligadas à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>. A sua atividade de rede em apps de trabalho, incluindo dados de navegação e emails, está visível para o seu administrador de TI e fornecedor de VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"As suas apps pessoais estão ligadas à Internet através da app <xliff:g id="VPN_APP">%1$s</xliff:g>. A sua atividade de rede, incluindo dados de navegação e emails, está visível para o seu fornecedor de VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir as definições de VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerido pelos teus pais, que podem ver e gerir informações como as apps que utilizas, a tua localização e o tempo de utilização."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ativar quando for provável que a bateria se esgote"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar pilha SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome da transmissão"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Palavra-passe"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Guardar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"A iniciar…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não é possível transmitir"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index f1f0532..17cac71 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tente fazer a captura de tela novamente"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Não foi possível salvar a captura de tela"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"O app ou a organização não permitem capturas de tela"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"A organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Este dispositivo pertence à sua organização e está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando o <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Este dispositivo pertence à sua organização"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Este dispositivo pertence à sua organização e está conectado à Internet usando VPNs"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e está conectado à Internet usando VPNs"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Sua organização pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> pode monitorar o tráfego de rede no seu perfil de trabalho"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"A atividade de rede do perfil de trabalho fica visível para o administrador de TI"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"A rede pode ser monitorada"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Este dispositivo está conectado à Internet usando VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Este dispositivo é fornecido pela <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gerenciamento de dispositivos"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Uma autoridade de certificação foi instalada neste dispositivo. É possível monitorar ou modificar seu tráfego de rede seguro."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"O administrador ativou o registro de rede, que monitora o tráfego no seu dispositivo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"O administrador ativou o registro de rede, que monitora o tráfego no seu perfil de trabalho, mas não no perfil pessoal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Este dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Seu dispositivo está conectado à Internet usando o <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Seus apps de trabalho estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede em apps de trabalho, incluindo e-mails e dados de navegação, estão visíveis para o administrador de TI e o provedor de VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Seus apps pessoais estão conectados à Internet usando o <xliff:g id="VPN_APP">%1$s</xliff:g>. Suas atividades de rede, incluindo e-mails e dados de navegação, estão visíveis para o provedor de VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Abrir configurações de VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu pai/mãe, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Ativada quando há possibilidade de a bateria acabar"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Não"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Despejar heap SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
@@ -855,16 +847,18 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Nome da transmissão"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Senha"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvar"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iniciando…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
<string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string>
<string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string>
- <string name="no_conversations_text" msgid="5354115541282395015">"Suas conversas recentes serão exibidas aqui"</string>
+ <string name="no_conversations_text" msgid="5354115541282395015">"Suas conversas recentes vão aparecer aqui"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string>
<string name="days_timestamp" msgid="5821854736213214331">"Há <xliff:g id="DURATION">%1$s</xliff:g> dias"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 17ae47e..2319305 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Încercați să faceți din nou o captură de ecran"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Nu se poate salva captura de ecran"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Editați"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Editați captura de ecran"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Trimiteți captura de ecran"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația dvs. deține acest dispozitiv și poate monitoriza traficul de rețea"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> deține acest dispozitiv și poate monitoriza traficul din rețea"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la internet prin aplicația <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Dispozitivul aparține organizației dvs."</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Acest dispozitiv aparține organizației dvs. și este conectat la internet prin rețele VPN."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> și este conectat la internet prin rețele VPN."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Este posibil ca organizația dvs. să monitorizeze traficul de rețea în profilul dvs. de serviciu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Este posibil ca <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> să monitorizeze traficul de rețea din profilul dvs. de serviciu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Adminul IT poate vedea profilul de serviciu"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Este posibil ca rețeaua să fie monitorizată"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Acest dispozitiv este conectat la internet prin rețele VPN."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Aplicațiile dvs. pentru lucru sunt conectate la internet prin <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Aplicațiile dvs. personale sunt conectate la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Acest dispozitiv este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Acest dispozitiv este oferit de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestionarea dispozitivului"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Pe acest dispozitiv este instalat un certificat CA. Traficul dvs. sigur de rețea poate fi monitorizat sau modificat."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratorul dvs. a activat înregistrarea în jurnal pentru rețea, funcție ce monitorizează traficul de pe dispozitivul dvs."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratorul a activat înregistrarea în jurnal pentru rețea, funcție ce monitorizează traficul în profilul dvs. de serviciu, dar nu și în profilul personal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Acest dispozitiv este conectat la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>. Activitatea în rețea, inclusiv e-mailurile și datele de navigare, sunt vizibile pentru administratorul IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Acest dispozitiv este conectat la internet prin aplicațiile <xliff:g id="VPN_APP_0">%1$s</xliff:g> și <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Activitatea în rețea, inclusiv e-mailurile și datele de navigare, sunt vizibile pentru administratorul IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Aplicațiile dvs. pentru lucru sunt conectate la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>. Activitatea în rețea cu aplicațiile pentru lucru, inclusiv e-mailurile și datele de navigare, sunt vizibile pentru administratorul IT și pentru furnizorul de servicii VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Aplicațiile dvs. personale sunt conectate la internet prin aplicația <xliff:g id="VPN_APP">%1$s</xliff:g>. Activitatea în rețea, inclusiv e-mailurile și datele de navigare, sunt vizibile pentru furnizorul de servicii VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Deschideți Setări VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dispozitivul este gestionat de unul dintre părinți. Părintele poate să vadă și să gestioneze informații cum ar fi aplicațiile pe care le folosești, locația ta și durata de folosire a dispozitivului."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Porniți dacă este probabil ca bateria să se descarce"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nu, mulțumesc"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Extrageți memoria SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicațiile folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" și "</string>
@@ -861,9 +853,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Numele transmisiei"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Parolă"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Salvați"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Începe…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nu se poate transmite"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 523b25b..effff8b 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Попробуйте сделать скриншот снова."</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Не удалось сохранить скриншот."</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Изменить"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Изменить скриншот"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Поделиться скриншотом"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" управляет этим устройством и может отслеживать сетевой трафик"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\"."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Это устройство принадлежит вашей организации и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сервис \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Это устройство принадлежит вашей организации"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Это устройство принадлежит вашей организации и подключено к интернету через сети VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Это устройство принадлежит организации \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" и подключено к интернету через сети VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Ваша организация может отслеживать сетевой трафик в рабочем профиле"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Организация \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" может отслеживать сетевой трафик в вашем рабочем профиле"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"История действий в сети доступна администратору в рабочем аккаунте."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Сеть может отслеживаться"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Это устройство подключено к интернету через сети VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Рабочие приложения подключены к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ваши личные приложения подключены к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Это устройство подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Устройство предоставлено компанией \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управление устройством"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"Настройки VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На устройстве установлен сертификат ЦС. Ваш защищенный сетевой трафик могут отслеживать и изменять."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администратор включил ведение сетевого журнала, чтобы отслеживать трафик на вашем устройстве."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администратор включил ведение сетевого журнала, чтобы отслеживать трафик в вашем рабочем профиле (информация из личного профиля не собирается)."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Это устройство подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Это устройство подключено к интернету через сервисы \"<xliff:g id="VPN_APP_0">%1$s</xliff:g>\" и \"<xliff:g id="VPN_APP_1">%2$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Рабочие приложения подключены к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши сетевые действия в этих приложениях, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору и поставщику услуг VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Личные приложения подключены к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны вашему поставщику услуг VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Открыть настройки VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Этим устройством управляет один из твоих родителей. Он может видеть, например, какими приложениями ты пользуешься и где находишься, а также задавать определенные настройки (например, ограничивать время использования устройства)."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Включать, если высока вероятность, что батарея скоро разрядится"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Нет, спасибо"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Передача SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Название трансляции"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Пароль"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сохранить"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запуск…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не удалось запустить трансляцию"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 85ac4a8..b9c5720 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"තිර රුව නැවත ගැනීමට උත්සාහ කරන්න"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"තිර රුව සුරැකීමට නොහැකිය"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"තිර රූ ගැනීමට යෙදුම හෝ ඔබගේ සංවිධානය ඉඩ නොදේ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"සංස්කරණය කරන්න"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"තිර රුව සංස්කරණය කරන්න"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"තිර රුව බෙදා ගන්න"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් සැපයේ"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"මෙම උපාංගය ඔබගේ සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිති අතර <xliff:g id="VPN_APP">%2$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිතිය"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"මෙම උපාංගය ඔබගේ සංවිධානයට අයිති අතර VPN හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> සංවිධානයට අයිති අතර VPN හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"ඔබගේ කාර්යාල පැතිකඩ තුළ ඔබේ සංවිධානය ජාල තදබදය නිරීක්ෂණය කිරීමට හැක"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ඔබේ කාර්යාල පැතිකඩ තුළ ජාල තදබදය නිරීක්ෂණය කළ හැක"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"කාර්යාල පැතිකඩ ජාල ක්රියාකාරකම් ඔබගේ IT පරිපාලකට දෘශ්යමානය"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"මෙම උපාංගය VPN හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"ඔබගේ කාර්යාල යෙදුම් <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"ඔබගේ පුද්ගලික යෙදුම් <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"මෙම උපාංගය <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් සැපයේ"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"උපාංග කළමනාකරණය"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"මෙම උපාංගය තුළ සහතික අධිකාරියක් ස්ථාපනය කර තිබේ. ඔබගේ ආරක්ෂක ජාල තදබදය නිරීක්ෂණය හෝ වෙනස් කිරීමට පුළුවනි."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ඔබගේ පරිපාලක ඔබගේ උපාංගය මත තදබදය නිරීක්ෂණය කරන ජාල ලොග් කිරීම ක්රියාත්මක කර ඇත."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ඔබගේ පරිපාලක ඔබගේ පුද්ගලික පැතිකඩෙහි නොව කාර්යාල පැතිකඩෙහි තදබදය නිරීක්ෂණය කරන, ජාල පිරීම ක්රියාත්මක කර ඇත."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"මෙම උපාංගය <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත. ඉ-තැපැල් සහ බ්රවුස් කිරීමේ දත්ත ඇතුළුව, ඔබගේ ජාල ක්රියාකාරකම්, ඔබගේ IT පරිපාලකට දෘශ්යමාන වේ."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"මෙම උපාංගය <xliff:g id="VPN_APP_0">%1$s</xliff:g> සහ <xliff:g id="VPN_APP_1">%2$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත. ඉ-තැපැල් සහ බ්රවුස් කිරීමේ දත්ත ඇතුළුව, ඔබගේ ජාල ක්රියාකාරකම්, ඔබගේ IT පරිපාලකට දෘශ්යමාන වේ."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ඔබගේ කාර්යාල යෙදුම් <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත. ඉ-තැපැල් සහ බ්රවුස් කිරීමේ දත්ත ඇතුළුව, කාර්යාල යෙදුම්වල ඔබගේ ජාල ක්රියාකාරකම්, ඔබගේ IT පරිපාලක සහ VPN සැපයුම්කරුට දෘශ්යමාන වේ."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"ඔබගේ පුද්ගලික යෙදුම් <xliff:g id="VPN_APP">%1$s</xliff:g> හරහා අන්තර්ජාලයට සම්බන්ධ කර ඇත. ඉ-තැපැල් සහ බ්රවුස් කිරීමේ දත්ත ඇතුළුව, ඔබගේ ජාල ක්රියාකාරකම්, ඔබගේ VPN සැපයුම්කරුට දෘශ්යමාන වේ."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN සැකසීම් විවෘත කරන්න"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"මෙම උපාංගය ඔබගේ මාපියන් විසින් කළමනාකරණය කෙරේ. ඔබ භාවිත කරන යෙදුම්, ඔබගේ ස්ථානය සහ ඔබගේ තිර කාලය වැනි තොරතුරු ඔබගේ මාපියන්ට බැලීමට සහ කළමනාකරණය කිරීමට හැකිය."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"බැටරිය අවසන් වීමට යන විට සක්රීය කරන්න"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"එපා ස්තූතියි"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"යෙදුම් ඔබේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරමින් සිටී."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" සහ "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"විකාශන නම"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"මුරපදය"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"සුරකින්න"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"ආරම්භ කරමින්…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"විකාශනය කළ නොහැකිය"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 512d9a5..b54d7b6 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Skúste snímku urobiť znova"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Snímka obrazovky sa nedá uložiť"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Upraviť"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Upraviť snímku obrazovky"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Zdieľať snímku obrazovky"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> vlastní toto zariadenie a môže sledovať sieťovú premávku"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Toto zariadenie poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Toto zariadenie patrí vašej organizácii"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Toto zariadenie patrí vašej organizácii a k internetu je pripojené prostredníctvom sietí VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Toto zariadenie patrí organizácii <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> a k internetu je pripojené prostredníctvom sietí VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizácia môže sledovať sieťovú premávku vo vašom pracovnom profile"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Organizácia <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> môže sledovať sieťovú premávku vo vašom pracovnom profile"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktivitu pracovného profilu na sieti vidí váš správca IT"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Sieť môže byť sledovaná"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Toto zariadenie je k internetu pripojené prostredníctvom sietí VPN."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše pracovné aplikácie sú k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše osobné aplikácie sú k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Toto zariadenie poskytuje <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Správa zariadení"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V tomto zariadení je nainštalovaná certifikačná autorita. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Správca aktivoval zapisovanie do denníka siete, ktoré sleduje premávku na vašom zariadení."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Správca aktivoval zapisovanie do denníka siete, ktoré sleduje premávku vo vašom pracovnom profile, ale nie osobnom."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí váš správca IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácií <xliff:g id="VPN_APP_0">%1$s</xliff:g> a <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí váš správca IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše pracovné aplikácie sú k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti v pracovných aplikáciách vrátane e‑mailov a dát prehliadania vidí váš správca IT a poskytovateľ siete VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše osobné aplikácie sú k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí váš poskytovateľ siete VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Otvoriť nastavenia pripojenia VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zariadenie spravuje tvoj rodič. Vidí a môže spravovať informácie, napríklad aplikácie, ktoré používaš, tvoju polohu a čas používania."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Zapnite, keď je batéria takmer vybitá"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nie, vďaka"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Výpis haldy SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Názov vysielania"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Heslo"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Uložiť"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Spúšťa sa…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nedá sa vysielať"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 87bb64d..4d21c56 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Poskusite znova ustvariti posnetek zaslona"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Posnetka zaslona ni mogoče shraniti"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Aplikacija ali vaša organizacija ne dovoljuje posnetkov zaslona"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Urejanje posnetka zaslona"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Deljenje posnetka zaslona"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Organizacija <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> je lastnica te naprave in lahko nadzira omrežni promet"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"To napravo zagotavlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Ta naprava pripada vaši organizaciji in je povezana z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in je povezana z internetom prek omrežja <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Ta naprava pripada vaši organizaciji"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Ta naprava pripada vaši organizaciji in je povezana z internetom prek omrežij VPN."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> in je povezana z internetom prek omrežij VPN."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Vaša organizacija lahko nadzira omrežni promet v vašem delovnem profilu"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> lahko nadzira omrežni promet v vašem delovnem profilu"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Omrežna dejavnost delovnega profila je vidna skrbniku za IT."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Omrežje je morda nadzorovano"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Ta naprava je povezana z internetom prek omrežij VPN."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vaše delovne aplikacije so povezane z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vaše osebne aplikacije so povezane z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Ta naprava je povezana z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"To napravo zagotavlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Upravljanje naprav"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V tej napravi je nameščen overitelj potrdil. Varni omrežni promet se lahko nadzira ali spreminja."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Skrbnik je vklopil beleženje omrežnega prometa, ki nadzira promet v napravi."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Skrbnik je vklopil beleženje omrežnega prometa, ki nadzoruje samo promet v delovnem profilu, tistega v osebnem profilu pa ne."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Ta naprava je povezana z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša omrežna dejavnost, vključno z e-pošto in podatki brskanja, je vidna skrbniku za IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Ta naprava je povezana z internetom prek omrežij <xliff:g id="VPN_APP_0">%1$s</xliff:g> in <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša omrežna dejavnost, vključno z e-pošto in podatki brskanja, je vidna skrbniku za IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše delovne aplikacije so povezane z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša omrežna dejavnost v delovnih aplikacijah, vključno z e-pošto in podatki brskanja, je vidna skrbniku za IT in ponudniku omrežja VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vaše osebne aplikacije so povezane z internetom prek omrežja <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša omrežna dejavnost, vključno z e-pošto in podatki brskanja, je vidna ponudniku omrežja VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Odpri nastavitve omrežja VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"To napravo upravlja tvoj starš. Lahko si ogleda in upravlja podatke, na primer katere aplikacije uporabljaš, tvojo lokacijo in koliko časa uporabljaš napravo."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Vklop, če je verjetno, da se bo baterija izpraznila"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ne, hvala"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Izvoz kopice SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije uporabljajo <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" in "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Ime oddajanja"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Geslo"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Shrani"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Začenjanje …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Oddajanje ni mogoče"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 9ce5105..d0cf883 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Provo ta nxjerrësh përsëri pamjen e ekranit"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Pamja e ekranit nuk mund të ruhet"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Modifiko"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Modifiko pamjen e ekranit"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Ndaj pamjen e ekranit"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Kjo pajisje ofrohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Kjo pajisje i përket organizatës sate dhe është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kjo pajisje i përket organizatës sate"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Kjo pajisje i përket organizatës sate dhe është e lidhur me internetin nëpërmjet VPN-ve"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> dhe është e lidhur me internetin nëpërmjet VPN-ve"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organizata jote mund të monitorojë trafikun e rrjetit në profilin tënd të punës"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> mund të monitorojë trafikun e rrjetit në profilin tënd të punës"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Aktiviteti i rrjetit të profilit të punës është i dukshëm për administratorin tënd të teknologjisë së informacionit"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Rrjeti mund të jetë i monitoruar"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Kjo pajisje është e lidhur me internetin nëpërmjet VPN-ve"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Aplikacionet e tua të punës janë të lidhura me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Aplikacionet e tua personale janë të lidhura me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Kjo pajisje ofrohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Menaxhimi i pajisjes"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Në këtë pajisje është instaluar një autoritet certifikate. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratori ka aktivizuar regjistrimin e rrjetit, i cili monitoron trafikun në pajisjen tënde."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratori yt ka aktivizuar regjistrimin e rrjetit, i cili monitoron trafikun në profilin tënd të punës, por jo në profilin tënd personal."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për administratorin tënd të teknologjisë së informacionit."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP_0">%1$s</xliff:g> dhe <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për administratorin tënd të teknologjisë së informacionit."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Aplikacionet e tua të punës janë të lidhura me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet në aplikacionet e punës, duke përfshirë email-et dhe të dhënat e shfletimit, është i dukshëm për administratorin e teknologjisë së informacionit dhe ofruesin e VPN-së."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Aplikacionet e tua personale janë të lidhura me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për ofruesin tënd të VPN-së."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Hap cilësimet e VPN-së"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kjo pajisje menaxhohet nga prindi yt. Prindi yt mund të shikojë dhe menaxhojë informacionet, si p.sh. aplikacionet që përdor, vendndodhjen tënde dhe kohën para ekranit."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktivizoje kur bateria mund të mbarojë"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Jo"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Hidh grumbullin SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacionet po përdorin <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dhe "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Emri i transmetimit"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Fjalëkalimi"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Ruaj"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Po fillon…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nuk mund të transmetohet"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index c40e3d5..53e047d 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Пробајте да поново направите снимак екрана"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Чување снимка екрана није успело"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Апликација или организација не дозвољавају прављење снимака екрана"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Измените снимак екрана"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Делите снимак екрана"</string>
@@ -368,28 +370,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> је власник овог уређаја и може да надгледа мрежни саобраћај"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Овај уређај припада вашој организацији и повезан је на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко: <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Овај уређај припада организацији"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Овај уређај припада вашој организацији и повезан је на интернет преко VPN-ова"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Власник овог уређаја је <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, а повезан је на интернет преко VPN-ова"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Организација може да прати мрежни саобраћај на пословном профилу"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> може да надгледа мрежни саобраћај на пословном профилу"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Активност на мрежи пословног профила је видљива ИТ администратору"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мрежа се можда надгледа"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Овај уређај је повезан на интернет преко VPN-ова"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Овај уређај пружа <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Управљање уређајима"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -405,14 +399,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На овом уређају је инсталиран ауторитет за издавање сертификата. Безбедни мрежни саобраћај може да се прати или мења."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администратор је укључио евидентирање мреже, које прати саобраћај на уређају."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администратор је укључио евидентирање мреже, које прати саобраћај на пословном профилу, али не и на личном профилу."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Овај уређај је повезан на интернет преко: <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је ИТ администратору."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ваше пословне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи у пословним апликацијама, укључујући имејлове и податке прегледања, видљива је ИТ администратору и добављачу VPN-а."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ваше личне апликације су повезане на интернет преко: <xliff:g id="VPN_APP">%1$s</xliff:g>. Ваша активност на мрежи, укључујући имејлове и податке прегледања, видљива је добављачу VPN-а."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Отвори подешавања VPN-а"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Овим уређајем управља родитељ. Родитељ може да види информације, као што су апликације које користиш, твоју локацију и време испред екрана, и да управља њима."</string>
@@ -735,6 +725,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Укључите ако ће батерија вероватно да се испразни"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Не, хвала"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Издвоји SysUI мем."</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
@@ -861,9 +853,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Назив емитовања"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Лозинка"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Сачувај"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Покреће се…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 82f09a9..cd1b18a 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Testa att ta en skärmbild igen"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Det gick inte att spara skärmbilden"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisationen tillåter inte att du tar skärmbilder"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Redigera"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Redigera skärmbild"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Dela skärmbild"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisationen äger den här enheten och kan övervaka nätverkstrafiken"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> äger den här enheten och kan övervaka nätverkstrafiken"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Enheten tillhandahålls av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Den här enheten tillhör organisationen och är ansluten till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> och är ansluten till internet via <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Den här enheten tillhör organisationen"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Den här enheten tillhör organisationen och är ansluten till internet via VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> och är ansluten till internet via VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Organisationen kan övervaka nätverkstrafik i jobbprofilen"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kan övervaka nätverkstrafiken i jobbprofilen"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Jobbprofilens nätverksaktivitet är synlig för IT-administratören"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Nätverket kan vara övervakat"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Den här enheten är ansluten till internet via VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Dina jobbappar är anslutna till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Dina privata appar är anslutna till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Den här enheten är ansluten till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Enheten tillhandahålls av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Enhetshantering"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"En certifikatutfärdare är installerad på enheten. Din säkra nätverkstrafik kan övervakas och ändras."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratören har aktiverat nätverksloggning som övervakar trafik på enheten."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratören har aktiverat nätverksloggning som övervakar trafik i jobbprofilen men inte den privata profilen."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Den här enheten är ansluten till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din nätverksaktivitet, till exempel e-post och webbinformation, är synlig för IT-administratören."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Den här enheten är ansluten till internet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> och <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Din nätverksaktivitet, till exempel e-post och webbinformation, är synlig för IT-administratören."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Dina jobbappar är anslutna till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din nätverksaktivitet i jobbappar, till exempel e-post och webbinformation, är synlig för IT-administratören och VPN-leverantören."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Dina privata appar är anslutna till internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Din nätverksaktivitet, till exempel e-post och webbinformation, är synlig för VPN-leverantören."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Öppna VPN-inställningarna"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Den här enheten hanteras av din förälder. Föräldern kan se och hantera information som vilka appar du använder, din plats och din skärmtid."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Aktivera när batteriet håller på att ta slut"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Nej tack"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI-heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> används av appar."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" och "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Utsändningsnamn"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Lösenord"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Spara"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Startar …"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Det gick inte att sända ut"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 561daa2..ca3cacd 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Jaribu kupiga picha ya skrini tena"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Imeshindwa kuhifadhi picha ya skrini"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Programu au shirika lako halikuruhusu kupiga picha za skrini"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Badilisha"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Badilisha picha ya skrini"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Shiriki picha ya skrini"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> inamiliki kifaa hiki na huenda ikafuatilia trafiki ya mtandao"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Kifaa hiki kimetolewa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Kifaa hiki kinamilikiwa na shirika lako"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Kifaa hiki kinamilikiwa na shirika lako na kimeunganishwa kwenye intaneti kupitia VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> na kimeunganishwa kwenye intaneti kupitia VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Huenda shirika lako likafuatilia shughuli kwenye mtandao katika wasifu wako wa kazini"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Huenda <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ikafuatilia shughuli kwenye mtandao katika wasifu wako wa kazini"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Shughuli za mtandao za wasifu wa kazini zinaonekana kwa msimamizi wako wa TEHAMA."</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Huenda mtandao unafuatiliwa"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Kifaa hiki kimeunganishwa kwenye intaneti kupitia VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Programu zako za kazini zimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Programu zako binafsi zimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Kifaa hiki kimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Kifaa hiki kimetolewa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Udhibiti wa kifaa"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Mamlaka ya cheti imesakinishwa kwenye kifaa hiki. Huenda shughuli kwenye mtandao wako salama zikafuatiliwa au kubadilishwa."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Msimamizi wako amewasha kumbukumbu ya kuingia mtandaoni, ambayo hufuatilia shughuli kwenye kifaa chako."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Msimamizi wako amewasha kumbukumbu ya kuingia mtandaoni ambayo hufuatilia shughuli kwenye wasifu wako wa kazini ila si kwenye wasifu wako wa binafsi."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Kifaa hiki kimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>. Shughuli zako za mtandaoni kwenye programu za kazini, ikijumuisha barua pepe na data ya kuvinjari, zinaonekana kwa msimamizi wako wa TEHAMA na mtoa huduma wa VPN."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Kifaa hiki kimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP_0">%1$s</xliff:g> na <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Shughuli zako za mtandaoni kwenye programu za kazini, ikijumuisha barua pepe na data ya kuvinjari, zinaonekana kwa msimamizi wako wa TEHAMA na mtoa huduma wa VPN."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Programu zako za kazini zimeunganishwa kwenye intaneti kupitia<xliff:g id="VPN_APP">%1$s</xliff:g>. Shughuli zako za mtandaoni kwenye programu za kazini, ikijumuisha barua pepe na data ya kuvinjari, zinaonekana kwa msimamizi wako TEHAMA na mtoa huduma wa VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Programu zako binafsi zimeunganishwa kwenye intaneti kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>. Shughuli zako za mtandaoni kwenye programu za kazini, ikijumuisha barua pepe na data ya kuvinjari, zinaonekana kwa mtoa huduma wako wa VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Fungua mipangilio ya VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kifaa hiki kinadhibitiwa na mzazi wako. Mzazi wako anaweza kuona na kudhibiti maelezo kama vile programu unazotumia, mahali ulipo na muda unaotumia kwenye kifaa."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Washa wakati betri inakaribia kuisha"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Hapana"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programu zinatumia <xliff:g id="TYPES_LIST">%s</xliff:g> yako."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" na "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Jina la Tangazo"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Nenosiri"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Hifadhi"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Inaanza…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Imeshindwa kutuma arifa"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index b3da144..6c42073 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -21,13 +21,20 @@
<dimen name="keyguard_indication_margin_bottom">25dp</dimen>
<dimen name="ambient_indication_margin_bottom">115dp</dimen>
<dimen name="lock_icon_margin_bottom">60dp</dimen>
-
- <dimen name="qs_media_session_height_expanded">172dp</dimen>
-
<!-- margin from keyguard status bar to clock. For split shade it should be
keyguard_split_shade_top_margin - status_bar_header_height_keyguard = 8dp -->
<dimen name="keyguard_clock_top_margin">8dp</dimen>
+ <!-- QS-->
+ <dimen name="qs_panel_padding_top">16dp</dimen>
+ <dimen name="qs_content_horizontal_padding">24dp</dimen>
+ <dimen name="qs_horizontal_margin">24dp</dimen>
+ <!-- in split shade qs_tiles_page_horizontal_margin should be equal of qs_horizontal_margin/2,
+ otherwise full space between two pages is qs_horizontal_margin*2, and that makes tiles page
+ not appear immediately after user swipes to the side -->
+ <dimen name="qs_tiles_page_horizontal_margin">12dp</dimen>
+ <dimen name="qs_media_session_height_expanded">172dp</dimen>
+
<dimen name="split_shade_notifications_scrim_margin_bottom">16dp</dimen>
<dimen name="notification_panel_margin_bottom">48dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 33d6f19..f45f106 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -26,6 +26,12 @@
<dimen name="status_bar_header_height_keyguard">56dp</dimen>
<dimen name="qs_media_session_height_expanded">251dp</dimen>
+ <dimen name="qs_content_horizontal_padding">40dp</dimen>
+ <dimen name="qs_horizontal_margin">40dp</dimen>
+ <!-- in split shade qs_tiles_page_horizontal_margin should be equal of qs_horizontal_margin/2,
+ otherwise full space between two pages is qs_horizontal_margin*2, and that makes tiles page
+ not appear immediately after user swipes to the side -->
+ <dimen name="qs_tiles_page_horizontal_margin">20dp</dimen>
<dimen name="lockscreen_shade_max_over_scroll_amount">42dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-port/dimens.xml b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
index fc12d41..2abc9e3 100644
--- a/packages/SystemUI/res/values-sw720dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -27,7 +27,7 @@
<dimen name="qqs_layout_padding_bottom">40dp</dimen>
- <dimen name="notification_panel_margin_horizontal">96dp</dimen>
+ <dimen name="notification_panel_margin_horizontal">80dp</dimen>
<dimen name="notification_side_paddings">40dp</dimen>
<dimen name="notification_section_divider_height">16dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 2a1c830..25529aa 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ஸ்கிரீன் ஷாட்டை மீண்டும் எடுக்க முயலவும்"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ஸ்கிரீன் ஷாட்டுகளை எடுப்பதை, ஆப்ஸ் அல்லது உங்கள் நிறுவனம் அனுமதிக்கவில்லை"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"திருத்து"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"ஸ்கிரீன்ஷாட்டைத் திருத்தும்"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"ஸ்கிரீன்ஷாட்டைப் பகிர்"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"இந்தச் சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்தால் வழங்கப்பட்டது"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"உங்கள் நிறுவனத்துக்குச் சொந்தமான இந்தச் சாதனம் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> என்ற நிறுவனத்துக்குச் சொந்தமான இந்தச் சாதனம் <xliff:g id="VPN_APP">%2$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> நிறுவனத்துக்கு சொந்தமானது"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"உங்கள் நிறுவனத்துக்குச் சொந்தமான இந்தச் சாதனம் VPNகள் மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> என்ற நிறுவனத்துக்குச் சொந்தமான இந்தச் சாதனம் VPNகள் மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"உங்கள் நிறுவனம் பணிக் கணக்கில் நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம்"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> உங்கள் பணிக் கணக்கில் நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம்"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"பணிக் கணக்கின் நெட்வொர்க் செயல்பாட்டை IT நிர்வாகியால் பார்க்க முடியும்"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"நெட்வொர்க் கண்காணிக்கப்படலாம்"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"இந்தச் சாதனம் VPNகள் மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"உங்கள் பணி ஆப்ஸ் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளன"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"உங்கள் தனிப்பட்ட ஆப்ஸ் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"இந்தச் சாதனம் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"இந்தச் சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்தால் வழங்கப்பட்டது"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"சாதன நிர்வாகம்"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரம் நிறுவப்பட்டுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"உங்கள் நிர்வாகி, நெட்வொர்க் பதிவெடுத்தலை இயக்கியுள்ளார். இது சாதனத்தில் ட்ராஃபிக்கைக் கண்காணிக்கும்."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"உங்கள் நிர்வாகி \'நெட்வொர்க் பதிவெடுத்தலை\' இயக்கியுள்ளார், இது உங்கள் பணிக் கணக்கில் டிராஃபிக்கைக் கண்காணிக்கும். ஆனால் தனிப்பட்ட கணக்கில் கண்காணிக்காது."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"இந்தச் சாதனம் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது. உங்களின் நெட்வொர்க் செயல்பாட்டை (மின்னஞ்சல்கள், உலாவிய தரவு உட்பட) உங்கள் IT நிர்வாகியால் பார்க்க முடியும்."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"இந்தச் சாதனம் <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> ஆகியவை மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது. உங்களின் நெட்வொர்க் செயல்பாட்டை (மின்னஞ்சல்கள், உலாவிய தரவு உட்பட) உங்கள் IT நிர்வாகியால் பார்க்க முடியும்."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"உங்கள் பணி ஆப்ஸ் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது. பணி ஆப்ஸில் உங்களின் நெட்வொர்க் செயல்பாட்டை (மின்னஞ்சல்கள், உலாவிய தரவு உட்பட) உங்கள் IT நிர்வாகியாலும் VPN வழங்குநராலும் பார்க்க முடியும்."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"உங்கள் தனிப்பட்ட ஆப்ஸ் <xliff:g id="VPN_APP">%1$s</xliff:g> மூலம் இணையத்துடன் இணைக்கப்பட்டுள்ளது. உங்களின் நெட்வொர்க் செயல்பாட்டை (மின்னஞ்சல்கள், உலாவிய தரவு உட்பட) உங்கள் VPN வழங்குநரால் பார்க்க முடியும்."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN அமைப்புகளைத் திற"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது. நீங்கள் பயன்படுத்தும் ஆப்ஸ், இருப்பிடம், பயன்படுத்திய நேரம் ஆகியவற்றைப் பார்க்கவும் நிர்வகிக்கவும் உங்கள் பெற்றோரால் முடியும்."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"பேட்டரி தீர்ந்துபோகும் நிலையில் இருக்கும் போது ஆன் செய்யப்படும்"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"வேண்டாம்"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" மற்றும் "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"பிராட்காஸ்ட்டின் பெயர்"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"கடவுச்சொல்"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"சேமி"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"தொடங்குகிறது…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ஒளிபரப்ப முடியவில்லை"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index d04d33f..f057fa9 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"స్క్రీన్షాట్ తీయడానికి మళ్లీ ప్రయత్నించండి"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"స్క్రీన్షాట్ను సేవ్ చేయడం సాధ్యపడలేదు"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"స్క్రీన్షాట్లు తీయడానికి యాప్ లేదా మీ సంస్థ అనుమతించలేదు"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ఎడిట్ చేయండి"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"స్క్రీన్షాట్ను ఎడిట్ చేయండి"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"స్క్రీన్షాట్ను షేర్ చేయండి"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ఈ పరికరం మీ సంస్థకు చెందినది, కాబట్టి అది నెట్వర్క్ ట్రాఫిక్ను పర్యవేక్షించవచ్చు"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"మీ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, కాబట్టి అది నెట్వర్క్ ట్రాఫిక్ను పర్యవేక్షించవచ్చు"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ద్వారా అందించబడింది"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"ఈ పరికరం మీ సంస్థకు చెందినది, <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, <xliff:g id="VPN_APP">%2$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"ఈ పరికరం మీ సంస్థకు చెందినది, VPNల ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>కు చెందినది, VPNల ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"మీ కార్యాలయ ప్రొఫైల్లోని నెట్వర్క్ ట్రాఫిక్ని మీ సంస్థ పర్యవేక్షించవచ్చు"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"మీ కార్యాలయ ప్రొఫైల్లోని నెట్వర్క్ ట్రాఫిక్ని <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> పర్యవేక్షించవచ్చు"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"వర్క్ ప్రొఫైల్ నెట్వర్క్ యాక్టివిటీ మీ IT అడ్మిన్కు కనిపిస్తుంది"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"నెట్వర్క్ పర్యవేక్షించబడవచ్చు"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"ఈ పరికరం VPNల ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"మీ వర్క్ యాప్లు <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడ్డాయి"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"మీ వ్యక్తిగత యాప్లు <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడ్డాయి"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"ఈ పరికరం <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ద్వారా అందించబడింది"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"పరికర నిర్వహణ"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ఈ పరికరంలో ప్రమాణపత్ర అధికారం ఇన్స్టాల్ చేయబడింది. మీ సురక్షిత నెట్వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"మీ నిర్వాహకులు మీ పరికరంలోని ట్రాఫిక్ని పర్యవేక్షించగల నెట్వర్క్ లాగింగ్ని ఆన్ చేశారు."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"మీ అడ్మిన్ నెట్వర్క్ లాగింగ్ను ఆన్ చేశారు, ఇది మీ వర్క్ ప్రొఫైల్లోని ట్రాఫిక్ను పర్యవేక్షిస్తుంది కానీ మీ వ్యక్తిగత ప్రొఫైల్లో కాదు."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"ఈ పరికరం <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది. ఈమెయిళ్లు, బ్రౌజింగ్ డేటాతో సహా మీ నెట్వర్క్ యాక్టివిటీ మీ IT అడ్మిన్కు కనిపిస్తుంది."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ఈ పరికరం <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడింది. ఈమెయిళ్లు, బ్రౌజింగ్ డేటాతో సహా మీ నెట్వర్క్ యాక్టివిటీ మీ IT అడ్మిన్కు కనిపిస్తుంది."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"మీ వర్క్ యాప్లు <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడ్డాయి. ఈమెయిళ్లు, బ్రౌజింగ్ డేటాతో సహా వర్క్ యాప్లలో మీ నెట్వర్క్ యాక్టివిటీ మీ IT అడ్మిన్కు, VPN ప్రొవైడర్కు కనిపిస్తుంది."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"మీ వ్యక్తిగత యాప్లు <xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా ఇంటర్నెట్కు కనెక్ట్ చేయబడ్డాయి. ఈమెయిళ్లు, బ్రౌజింగ్ డేటాతో సహా మీ నెట్వర్క్ యాక్టివిటీ మీ VPN ప్రొవైడర్కు కనిపిస్తుంది."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN సెట్టింగ్లను తెరవండి"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు. మీ తల్లి/తండ్రి, మీరు ఉపయోగించే యాప్లు, మీ లొకేషన్, అలాగే మీ పరికర వినియోగ వ్యవధి వంటి సమాచారాన్ని చూడగలరు, మేనేజ్ చేయగలరు."</string>
@@ -628,7 +618,7 @@
<string name="right_keycode" msgid="2480715509844798438">"కుడివైపు ఉన్న కీకోడ్"</string>
<string name="left_icon" msgid="5036278531966897006">"ఎడమ వైపు చిహ్నం"</string>
<string name="right_icon" msgid="1103955040645237425">"కుడివైపు ఉన్న చిహ్నం"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"టైల్లను జోడించడం కోసం పట్టుకుని, లాగండి"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"టైల్స్ను జోడించడానికి పట్టుకుని, లాగండి"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"టైల్ల క్రమం మార్చడానికి వాటిని పట్టుకుని, లాగండి"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"తీసివేయడానికి ఇక్కడికి లాగండి"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"మీ వద్ద కనీసం <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> టైల్లు ఉండాలి"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"వద్దు, ధన్యవాదాలు"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"డంప్ SysUI హీప్"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"అప్లికేషన్లు మీ <xliff:g id="TYPES_LIST">%s</xliff:g>ని ఉపయోగిస్తున్నాయి."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" మరియు "</string>
@@ -857,6 +849,10 @@
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"సేవ్ చేయండి"</string>
<string name="media_output_broadcast_starting" msgid="8130153654166235557">"ప్రారంభించబడుతోంది…"</string>
<string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ప్రసారం చేయడం సాధ్యపడలేదు"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
+ <skip />
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
+ <skip />
<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>
@@ -888,7 +884,7 @@
<string name="status_before_loading" msgid="1500477307859631381">"కంటెంట్ త్వరలో కనిపిస్తుంది"</string>
<string name="missed_call" msgid="4228016077700161689">"మిస్డ్ కాల్"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
- <string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్లు, మిస్స్డ్ కాల్స్, అలాగే స్టేటస్ అప్డేట్లను చూడండి"</string>
+ <string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్లు, మిస్డ్ కాల్స్, అలాగే స్టేటస్ అప్డేట్లను చూడండి"</string>
<string name="people_tile_title" msgid="6589377493334871272">"సంభాషణ"</string>
<string name="paused_by_dnd" msgid="7856941866433556428">"అంతరాయం కలిగించవద్దు ద్వారా పాజ్ చేయబడింది"</string>
<string name="new_notification_text_content_description" msgid="2915029960094389291">"<xliff:g id="NAME">%1$s</xliff:g> మెసేజ్ను పంపారు: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 622697e..e194b4d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -35,8 +35,7 @@
<string name="usb_device_permission_prompt" msgid="4414719028369181772">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม\nแอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่อาจเก็บเสียงผ่านอุปกรณ์ USB นี้ได้"</string>
<string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ใช่ไหม"</string>
- <!-- no translation found for usb_audio_device_confirm_prompt_title (8828406516732985696) -->
- <skip />
+ <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
<string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"แอปนี้ไม่ได้รับอนุญาตให้อัดเสียงแต่อาจเก็บเสียงเสียงผ่านอุปกรณ์ USB นี้ได้ การใช้ <xliff:g id="APPLICATION">%1$s</xliff:g> กับอุปกรณ์นี้อาจทำให้คุณไม่ได้ยินเสียงสายเรียกเข้า การแจ้งเตือน และการปลุก"</string>
<string name="usb_audio_device_prompt" msgid="7944987408206252949">"การใช้ <xliff:g id="APPLICATION">%1$s</xliff:g> กับอุปกรณ์นี้อาจทำให้คุณไม่ได้ยินเสียงสายเรียกเข้า การแจ้งเตือน และการปลุก"</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ไหม"</string>
@@ -79,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"ลองบันทึกภาพหน้าจออีกครั้ง"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"บันทึกภาพหน้าจอไม่ได้"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"แอปหรือองค์กรของคุณไม่อนุญาตให้จับภาพหน้าจอ"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"แก้ไข"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"แก้ไขภาพหน้าจอ"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"แชร์ภาพหน้าจอ"</string>
@@ -335,7 +336,7 @@
<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="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
- <string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</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>
@@ -366,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"อุปกรณ์นี้ให้บริการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"อุปกรณ์นี้เป็นขององค์กรและเชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"อุปกรณ์นี้เป็นของ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> และเชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> เป็นเจ้าของอุปกรณ์นี้"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"อุปกรณ์นี้เป็นขององค์กรและเชื่อมต่ออินเทอร์เน็ตผ่าน VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"อุปกรณ์นี้เป็นของ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> และเชื่อมต่ออินเทอร์เน็ตผ่าน VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"องค์กรของคุณอาจตรวจสอบการจราจรของข้อมูลในเครือข่ายในโปรไฟล์งาน"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> อาจตรวจสอบการจราจรของข้อมูลในเครือข่ายในโปรไฟล์งานของคุณ"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"ผู้ดูแลระบบไอทีจะเห็นกิจกรรมในเครือข่ายโปรไฟล์งาน"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"อาจมีการตรวจสอบเครือข่าย"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"อุปกรณ์นี้เชื่อมต่ออินเทอร์เน็ตผ่าน VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"แอปงานเชื่อมต่ออินเทอร์เน็ตผ่าน <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"แอปส่วนตัวเชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"อุปกรณ์นี้เชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"อุปกรณ์นี้ให้บริการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"การจัดการอุปกรณ์"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -403,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"มีการติดตั้งผู้ออกใบรับรองในอุปกรณ์นี้ อาจมีการตรวจสอบหรือแก้ไขการจราจรของข้อมูลในเครือข่ายที่ปลอดภัยของคุณ"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ผู้ดูแลระบบได้เปิดการบันทึกกิจกรรมของเครือข่าย ซึ่งจะตรวจสอบการรับส่งข้อมูลในอุปกรณ์ของคุณ"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ผู้ดูแลระบบได้เปิดการบันทึกกิจกรรมของเครือข่าย ซึ่งจะตรวจสอบการรับส่งข้อมูลในโปรไฟล์งานแต่ไม่ตรวจสอบในโปรไฟล์ส่วนตัวของคุณ"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"อุปกรณ์นี้เชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g> ผู้ดูแลระบบไอทีสามารถดูกิจกรรมที่คุณทำในเครือข่ายรวมถึงอีเมลและข้อมูลการท่องเว็บได้"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"อุปกรณ์นี้เชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP_0">%1$s</xliff:g> และ<xliff:g id="VPN_APP_1">%2$s</xliff:g> ผู้ดูแลระบบไอทีสามารถดูกิจกรรมที่คุณทำในเครือข่ายรวมถึงอีเมลและข้อมูลการท่องเว็บได้"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"แอปงานเชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g> ผู้ดูแลระบบไอทีและผู้ให้บริการ VPN สามารถดูกิจกรรมที่คุณทำในเครือข่ายในแอปงานได้ ซึ่งรวมถึงอีเมลและข้อมูลการท่องเว็บ"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"แอปส่วนตัวเชื่อมต่ออินเทอร์เน็ตผ่าน<xliff:g id="VPN_APP">%1$s</xliff:g> ผู้ให้บริการ VPN สามารถดูกิจกรรมที่คุณทำในเครือข่ายซึ่งรวมถึงอีเมลและข้อมูลการท่องเว็บได้"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"เปิดการตั้งค่า VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"อุปกรณ์นี้จัดการโดยผู้ปกครอง ผู้ปกครองจะดูและจัดการข้อมูลต่างๆ ได้ เช่น แอปที่คุณใช้ ตำแหน่งของคุณ และเวลาอยู่หน้าจอ"</string>
@@ -731,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"เปิดเมื่อมีแนวโน้มว่าแบตเตอรี่จะหมด"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"ไม่เป็นไร"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"หลายแอปพลิเคชันใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณอยู่"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" และ "</string>
@@ -856,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"ชื่อการออกอากาศ"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"รหัสผ่าน"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"บันทึก"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"กำลังเริ่มต้น…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ออกอากาศไม่ได้"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
@@ -887,7 +880,7 @@
<string name="audio_status" msgid="4237055636967709208">"กำลังฟัง"</string>
<string name="game_status" msgid="1340694320630973259">"กำลังเล่น"</string>
<string name="empty_user_name" msgid="3389155775773578300">"เพื่อน"</string>
- <string name="empty_status" msgid="5938893404951307749">"คืนนี้มาแชทกัน"</string>
+ <string name="empty_status" msgid="5938893404951307749">"คืนนี้คุยกันนะ"</string>
<string name="status_before_loading" msgid="1500477307859631381">"เนื้อหาจะแสดงขึ้นเร็วๆ นี้"</string>
<string name="missed_call" msgid="4228016077700161689">"สายที่ไม่ได้รับ"</string>
<string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index ae2c4f1..fb7fcc5 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Subukang kumuhang muli ng screenshot"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Hindi ma-save ang screenshot"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Hindi pinahihintulutan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"I-edit"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"I-edit ang screenshot"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Ibahagi ang screenshot"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Nagmula sa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Pagmamay-ari ng organisasyon mo ang device na ito at nakakonekta ito sa internet sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at nakakonekta ito sa internet sa pamamagitan ng <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Pag-aari ng organisasyon mo ang device na ito at nakakonekta ito sa internet sa pamamagitan ng VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang device na ito at nakakoenekta ito sa internet sa pamamagitan ng mga VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Maaaring sumubaybay ang iyong organisasyon ng trapiko sa network sa profile sa trabaho mo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Maaaring subaybayan ng <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ang trapiko sa network sa iyong profile sa trabaho"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Nakikita ng IT admin ang aktibidad sa network"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Maaaring sinusubaybayan ang network"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Nakakonekta ang device na ito sa internet sa pamamagitan ng mga VPN."</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Nakakonekta sa internet ang iyong mga app para sa trabaho sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Nakakonekta sa internet ang iyong mga personal na app sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Nakakonekta ang device na ito sa internet sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Nagmula sa <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Pamamahala ng device"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"May naka-install sa device na ito na isang awtoridad sa certificate. Maaaring subaybayan o baguhin ang iyong ligtas na trapiko sa network."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Na-on ng iyong admin ang pag-log sa network, na sumusubaybay sa trapiko sa device mo."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Na-on ng iyong admin ang pag-log sa network, na sumusubaybay sa trapiko sa profile mo sa trabaho pero hindi sa iyong personal na profile."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Nakakonekta ang device na ito sa internet sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>. Nakikita ng iyong IT admin ang aktibidad ng network, kasama ang mga email at data mula sa pag-browse."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Nakakonekta ang device na ito sa internet sa pamamagitan ng <xliff:g id="VPN_APP_0">%1$s</xliff:g> at <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Nakikita ng iyong IT admin ang aktibidad ng network, kasama ang mga email at data mula sa pag-browse."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Nakakonekta sa internet ang iyong mga app para sa trabaho sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>. Nakikita ng iyong IT admin at VPN provider ang aktibidad ng network sa app para sa trabaho, kasama ang mga email at data mula sa pag-browse."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Nakakonekta ang iyong mga personal na app sa internet sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>. Nakikita ng iyong VPN provider ang aktibidad ng network, kasama ang mga email at data mula sa pag-browse."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Buksan ang mga setting ng VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Pinapamahalaan ng iyong magulang ang device na ito. Makikita at mapapamahalaan ng iyong magulang ang impormasyon tulad ng mga app na ginagamit mo, iyong lokasyon, at tagal ng paggamit mo sa device."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"I-on kapag malamang na maubos ang baterya"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Hindi, salamat na lang"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ginagamit ng mga application ang iyong <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" at "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Pangalan ng Broadcast"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Password"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"I-save"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Nagsisimula…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Hindi makapag-broadcast"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index dbd6f6b..7acd4c8 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -78,10 +78,12 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Tekrar ekran görüntüsü almayı deneyin"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ekran görüntüsü kaydedilemiyor"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Düzenle"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Ekran görüntüsünü düzenle"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Ekranı paylaş"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Daha fazla ekran görüntüsü al"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Alanı genişlet"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran görüntüsünü kapat"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran görüntüsü önizlemesi"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Üst sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait olup ağ trafiği bu kuruluş tarafından izlenebilir"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından sağlanmaktadır"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Bu cihaz, kuruluşunuza ait olup internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kuruluşuna ait olup internete <xliff:g id="VPN_APP">%2$s</xliff:g> üzerinden bağlı"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu cihaz, kuruluşunuza ait"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> adlı kuruluşa ait"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Bu cihaz, kuruluşunuza ait olup internete VPN\'ler üzerinden bağlı"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> kuruluşuna ait olup internete VPN\'ler üzerinden bağlı"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Kuruluşunuz, iş profilinizdeki ağ trafiğini izleyebilir"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, iş profilinizdeki ağ trafiğini izleyebilir"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"BT yöneticiniz, iş profilinizin ağ etkinliğini görebilir"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Ağ trafiği izlenebilir"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Bu cihaz internete VPN\'ler üzerinden bağlı"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"İş uygulamalarınız internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Kişisel uygulamalarınız internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Bu cihaz internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu cihaz, <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından sağlanmaktadır"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Cihaz yönetimi"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Bu cihazda bir sertifika yetkilisi yüklü. Güvenli ağ trafiğiniz izlenebilir veya değiştirilebilir."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Yöneticiniz,cihazınızdaki trafiği izleyen ağ günlük kaydını açtı."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Yöneticiniz, iş profilinizdeki trafiği izleyen ancak kişisel profilinizdeki trafiği izlemeyen ağ günlük kaydını açtı."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Bu cihaz internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı. E-postalar ve tarama verileri dahil olmak üzere ağ etkinliğiniz, BT yöneticinize görünür."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Bu cihaz internete <xliff:g id="VPN_APP_0">%1$s</xliff:g> ve <xliff:g id="VPN_APP_1">%2$s</xliff:g> üzerinden bağlı. E-postalar ve tarama verileri dahil olmak üzere ağ etkinliğiniz, BT yöneticinize görünür."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"İş uygulamalarınız internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı. E-postalar ve tarama verileri dahil olmak üzere iş uygulamalarındaki ağ etkinliğiniz, BT yöneticinize ve VPN sağlayıcınıza görünür."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Kişisel uygulamalarınız internete <xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden bağlı. E-postalar ve tarama verileri dahil olmak üzere ağ etkinliğiniz, VPN sağlayıcınıza görünür."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ayarlarını aç"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz ebeveyniniz tarafından yönetiliyor. Kullandığınız uygulamalar, konumunuz ve ekran başında kalma süreniz gibi bilgiler ebeveyniniz tarafından görülüp yönetilebilir."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Piliniz bitecek gibiyse bu özelliği açın"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Hayır, teşekkürler"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI Yığın Dökümü"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Uygulamalar şunları kullanıyor: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ve "</string>
@@ -855,15 +847,17 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Yayın Adı"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Şifre"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Kaydet"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Başlatılıyor…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayınlanamıyor"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
<string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
<string name="select_conversation_title" msgid="6716364118095089519">"Görüşme widget\'ları"</string>
- <string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir ileti dizisine dokunun"</string>
+ <string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir görüşmeye dokunun"</string>
<string name="no_conversations_text" msgid="5354115541282395015">"Son görüşmeleriniz burada gösterilir"</string>
<string name="priority_conversations" msgid="3967482288896653039">"Öncelikli görüşmeler"</string>
<string name="recent_conversations" msgid="8531874684782574622">"Son görüşmeler"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index a9c7fe0..b49ac73 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Спробуйте зробити знімок екрана ще раз"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Не вдалося зберегти знімок екрана"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Додаток або адміністратор вашої організації не дозволяють робити знімки екрана"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Редагувати"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Редагувати знімок екрана"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Поділитися знімком екрана"</string>
@@ -371,28 +373,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\". Її адміністратор може відстежувати мережевий трафік"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Цей пристрій надано компанією \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Цей пристрій належить вашій організації. Його підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Цей пристрій належить організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>. Його підключено до Інтернету через <xliff:g id="VPN_APP">%2$s</xliff:g>."</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Цей пристрій належить вашій організації"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Цей пристрій належить вашій організації. Його підключено до Інтернету через мережі VPN."</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Цей пристрій належить організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>. Його підключено до Інтернету через мережі VPN."</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Адміністратор вашої організації може відстежувати мережевий трафік у вашому робочому профілі"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Адміністратор організації <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> мож відстежувати мережевий трафік у вашому робочому профілі"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Дії в мережі в робочому профілі може бачити ваш системний адміністратор"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Мережевий трафік може відстежуватися"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Цей пристрій підключено до Інтернету через мережі VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ваші робочі додатки підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ваші особисті додатки підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Цей пристрій підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Цей пристрій надано компанією \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Керування пристроями"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"Мережа VPN"</string>
@@ -408,14 +402,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На цьому пристрої встановлено центр сертифікації. Захищений мережевий трафік може відстежуватися або змінюватися."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Ваш адміністратор увімкнув журнал мережі, щоб відстежувати трафік на вашому пристрої."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Ваш адміністратор увімкнув журнал мережі, щоб відстежувати трафік вашого робочого профілю (не особистого)."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Цей пристрій підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>. Системний адміністратор бачить ваші дії в мережі, зокрема електронні листи й дані веб-перегляду."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Цей пристрій підключено до Інтернету через <xliff:g id="VPN_APP_0">%1$s</xliff:g> і <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Системний адміністратор бачить ваші дії в мережі, зокрема електронні листи й дані веб-перегляду."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ваші робочі додатки підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>. Системний адміністратор і постачальник послуг VPN бачать ваші дії в мережі в робочих додатках, зокрема електронні листи й дані веб-перегляду."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ваші особисті додатки підключено до Інтернету через <xliff:g id="VPN_APP">%1$s</xliff:g>. Постачальник послуг VPN бачить ваші дії в мережі, зокрема електронні листи й дані веб-перегляду."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Відкрити налаштування мережі VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Цим пристроєм керують твої батьки. Вони можуть бачити та контролювати, якими додатками ти користуєшся, де перебуваєш і скільки часу проводиш за пристроєм."</string>
@@ -740,6 +730,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Вмикати, коли заряд акумулятора закінчується"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Ні, дякую"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Додатки використовують <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
@@ -867,9 +859,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Назва трансляції"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Пароль"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Зберегти"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Запуск…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Неможливо транслювати"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6b3b3c0..5c8687d 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"دوبارہ اسکرین شاٹ لینے کی کوشش کریں"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"اسکرین شاٹ کو محفوظ نہیں کیا جا سکتا"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"ترمیم کریں"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"اسکرین شاٹ میں ترمیم کریں"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"اسکرین شاٹ کا اشتراک کریں"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"آپ کی تنظیم اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> نے فراہم کیا ہے"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"یہ آلہ آپ کی تنظیم کا ہے اور <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے اور <xliff:g id="VPN_APP">%2$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"یہ آلہ آپ کی تنظیم کا ہے"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"یہ آلہ آپ کی تنظیم کا ہے اور VPNs کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> کا ہے اور VPNs کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"آپ کی تنظیم آپ کے دفتری پروفائل میں نیٹ ورک ٹریفک مانیٹر کر سکتی ہے"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> آپ کے دفتری پروفائل میں نیٹ ورک ٹریفک مانیٹر کر سکتی ہے"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"آپ کا IT منتظم دفتری پروفائل نیٹ ورک کی سرگرمی دیکھ سکتا ہے۔"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"نیٹ ورک کو مانیٹر کیا جا سکتا ہے"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"یہ آلہ VPNs کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"آپ کی ورک ایپس <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہیں"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"آپ کی ذاتی ایپس <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہیں"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"یہ آلہ <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہے"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> نے فراہم کیا ہے"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"آلے کا نظم و نسق"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ایک سرٹیفکیٹ کی اتھارٹی اس آلہ پر انسٹال ہے۔ آپ کا محفوظ نیٹ ورک ٹریفک مانیٹر ہو سکتا ہے یا اس میں ترمیم کی جا سکتی ہے۔"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"آپ کے منتظم نے نیٹ ورک لاگنگ کو آن کر دیا ہے، جو آپ کے آلے پر ٹریفک مانیٹر کرتی ہے۔"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"آپ کے منتظم نے نیٹ ورک لاگنگ آن کر دی ہے، جو آپ کے ذاتی پروفائل پر نہیں بلکہ دفتری پروفائل پر ٹریفک کو مانیٹر کرتی ہے۔"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"یہ آلہ <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہے۔ آپ کا IT منتظم ای میلز اور براؤزر ڈیٹا سمیت آپ کے نیٹ ورک کی سرگرمی دیکھ سکتا ہے۔"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"یہ آلہ <xliff:g id="VPN_APP_0">%1$s</xliff:g> اور <xliff:g id="VPN_APP_1">%2$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہے۔ آپ کا IT منتظم ای میلز اور براؤزر ڈیٹا سمیت آپ کے نیٹ ورک کی سرگرمی دیکھ سکتا ہے۔"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"آپ کی ورک ایپس <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہیں۔ آپ کے IT منتظم اور VPN فراہم کنندہ ای میلز اور براؤزر ڈیٹا سمیت ورک ایپس میں آپ کے نیٹ ورک کی سرگرمی دیکھ سکتے ہیں۔"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"آپ کی ذاتی ایپس <xliff:g id="VPN_APP">%1$s</xliff:g> کے ذریعے انٹرنیٹ سے منسلک ہیں۔ آپ کا VPN فراہم کنندہ ای میلز اور براؤزر ڈیٹا سمیت آپ کے نیٹ ورک کی سرگرمی دیکھ سکتا ہے۔"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN کی ترتیبات کھولیں"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"یہ آلہ آپ کے والدین کے زیر انتظام ہے۔ آپ کے والدین آپ کی استعمال والی ایپس، آپ کا مقام اور آپ کے اسکرین کے وقت جیسی معلومات کو دیکھ اور اس کا نظم کر سکتے ہیں۔"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"جب بیٹری کے ختم ہونے کا امکان ہو تو آن کریں"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"نہیں شکریہ"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ایپلیکیشنز آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں۔"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" اور "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"براڈکاسٹ کا نام"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"پاس ورڈ"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"محفوظ کریں"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"شروع ہو رہا ہے…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"براڈکاسٹ نہیں کیا جا سکتا"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 8c8eca8..9b8edec 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -78,10 +78,12 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Qayta skrinshot olib ko‘ring"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Skrinshot saqlanmadi"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Tahrirlash"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinshotni tahrirlash"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Skrinshot yuborish"</string>
- <string name="screenshot_scroll_label" msgid="2930198809899329367">"Yana suratga olish"</string>
+ <string name="screenshot_scroll_label" msgid="2930198809899329367">"Skrinshot sohasini kengaytirish"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"Skrinshotni yopish"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"Skrinshotga razm solish"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Yuqori chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
@@ -365,27 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va tarmoq trafigi tashkilot tomonidan kuzatilishi mumkin"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan berilgan."</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Bu qurilma tashkilotingizga tegishli va internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va internetga <xliff:g id="VPN_APP">%2$s</xliff:g> orqali ulangan"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Bu qurilma tashkilotingizga tegishli"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Bu qurilma tashkilotingizga tegishli va internetga VPN tarmoqlari orqali ulangan"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> tashkilotiga tegishli va internetga VPN tarmoqlari orqali ulangan"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tashkilotingiz ishchi profilingizda tarmoq trafigini nazorat qilishi mumkin"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ishchi profilingizda tarmoq trafigini nazorat qilishi mumkin"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Ish profilida tarmoqqa oid harakatlar AT administratoriga koʻrinadi"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Tarmoq kuzatilishi mumkin"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Bu qurilma internetga VPN tarmoqlari orqali ulangan"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ishga oid ilovalar internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan"</string>
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Shaxsiy ilovalaringiz internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Bu qurilma internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan berilgan."</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Qurilmalar boshqaruvi"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -401,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Qurilmada CA sertifikati o‘rnatilgan. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator qurilmangizdagi trafikni nazorat qiluvchi tarmoq jurnalini yuritishni faollashtirgan."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator ish profilingizdagi trafikni nazorat qiluvchi tarmoq jurnalini yuritishni faollashtirgan (shaxsiy profildan maʼlumotlar olinmaydi)."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Bu qurilma internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan. Emaillar va brauzer tarixi kabi tarmoq harakatlaringiz AT administratoriga koʻrinadi."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Bu qurilma internet <xliff:g id="VPN_APP_0">%1$s</xliff:g> va <xliff:g id="VPN_APP_1">%2$s</xliff:g> orqali ulangan. Emaillar va brauzer tarixi kabi tarmoq harakatlaringiz AT administratoriga koʻrinadi."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ishga oid ilovalar internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan. Ishga oid ilovalarda emaillar va brauzer tarixi kabi tarmoq harakatlaringiz AT administratori va VPN provayderiga koʻrinadi."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Shaxsiy ilovalaringiz internetga <xliff:g id="VPN_APP">%1$s</xliff:g> orqali ulangan. Emaillar va brauzer tarixi kabi tarmoq harakatlaringiz VPN provayderiga koʻrinadi."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN sozlamalarini ochish"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu – ota-onangiz tomonidan boshqariladigan qurilma. Ota-onangiz siz foydalangan ilovalar, joylashuvingiz va qurilmadan foydalanish vaqti kabi axborotlarni koʻrishi va boshqarishi mumkin."</string>
@@ -729,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Batareya quvvati kamayishi aniqlanganda yoqilsin"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Kerak emas"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ilovalarda ishlatilmoqda: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" va "</string>
@@ -854,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Translatsiya nomi"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Parol"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Saqlash"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Ishga tushmoqda…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Uzatilmadi"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index eb03841..1a8bebb 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Hãy thử chụp lại màn hình"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Không thể lưu ảnh chụp màn hình"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Chỉnh sửa"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Chỉnh sửa ảnh chụp màn hình"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Chia sẻ ảnh chụp màn hình"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Thiết bị này do <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> cung cấp"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Thiết bị này thuộc sở hữu của tổ chức của bạn và được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Thiết bị này thuộc sữu hữu của <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> và được kết nối với Internet thông qua <xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Thiết bị này thuộc về tổ chức của bạn"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Thiết bị này thuộc sở hữu của tổ chức của bạn và được kết nối với Internet thông qua VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Thiết bị này thuộc sở hữu của <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> và được kết nối với Internet thông qua VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tổ chức của bạn có thể giám sát lưu lượng truy cập mạng trong hồ sơ công việc của bạn"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> có thể giám sát lưu lượng truy cập mạng trong hồ sơ công việc của bạn"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Quản trị viên CNTT có thể xem hoạt động trên mạng của hồ sơ công việc"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Mạng có thể được giám sát"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Thiết bị này được kết nối với Internet thông qua VPNs"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ứng dụng công việc của bạn được kết nối internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>."</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ứng dụng cá nhân của bạn được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Thiết bị này được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Thiết bị này do <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> cung cấp"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Quản lý thiết bị"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Một tổ chức phát hành chứng chỉ được cài đặt trên thiết bị này. Lưu lượng truy cập mạng bảo mật của bạn có thể được giám sát hoặc sửa đổi."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Quản trị viên của bạn đã bật tính năng ghi nhật ký mạng. Tính năng này giám sát lưu lượng truy cập trên thiết bị của bạn."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Quản trị viên của bạn đã bật tính năng ghi nhật ký mạng. Tính năng này giám sát lưu lượng truy cập trong hồ sơ công việc chứ không giám sát lưu lượng truy cập trong hồ sơ cá nhân của bạn."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Thiết bị này được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>. Hoạt động mạng bao gồm email và dữ liệu duyệt web sẽ được hiển thị cho quản trị viên CNTT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Thiết bị này được kết nối với Internet thông qua <xliff:g id="VPN_APP_0">%1$s</xliff:g> và <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Hoạt động mạng bao gồm email và dữ liệu duyệt web sẽ được hiển thị cho quản trị viên CNTT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ứng dụng công việc của bạn được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>. Hoạt động mạng trong các ứng dụng công việc, bao gồm email và dữ liệu duyệt web sẽ được hiển thị cho quản trị viên CNTT và nhà cung cấp VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ứng dụng cá nhân được kết nối với Internet thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>. Hoạt động mạng của bạn, bao gồm email và dữ liệu duyệt web, được hiển thị cho nhà cung cấp VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Mở cài đặt VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Thiết bị này do cha mẹ bạn quản lý. Cha mẹ có thể có thể xem và quản lý những thông tin như ứng dụng bạn dùng, vị trí của bạn và thời gian bạn sử dụng thiết bị."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Bật khi pin sắp hết"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Không, cảm ơn"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Trích xuất bộ nhớ SysUI"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" và "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Tên thiết bị truyền"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Mật khẩu"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Lưu"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Đang bắt đầu…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Không thể truyền"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index d0f914d..cae4870 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"请再次尝试截屏"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"无法保存屏幕截图"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"此应用或您所在的单位不允许进行屏幕截图"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"编辑"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"编辑屏幕截图"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"分享屏幕截图"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>拥有此设备,且可能会监控网络流量"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此设备由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>提供"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此设备归贵组织所有,已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有,已通过“<xliff:g id="VPN_APP">%2$s</xliff:g>”连接到互联网"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此设备归贵单位所有"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此设备归贵组织所有,已通过 VPN 连接到互联网"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"此设备归<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>所有,已通过 VPN 连接到互联网"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"您所在的单位可能会监控您工作资料中的网络流量"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"“<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>”可能会监控您工作资料中的网络流量"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理员可以看到工作资料的网络活动记录"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"网络可能会受到监控"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"此设备已通过 VPN 连接到互联网"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"您的工作应用已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"您的个人应用已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"此设备已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"此设备由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>提供"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"设备管理"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此设备上已安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"您的管理员已开启网络日志记录功能(该功能会监控您设备上的流量)。"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"您的管理员已开启网络日志记录功能,该功能会监控您的工作资料的流量,但不会监控您个人资料的流量。"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"此设备已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。您的 IT 管理员可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此设备已通过“<xliff:g id="VPN_APP_0">%1$s</xliff:g>”和“<xliff:g id="VPN_APP_1">%2$s</xliff:g>”连接到互联网。您的 IT 管理员可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"您的工作应用已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。您的 IT 管理员和 VPN 提供商可以查看工作应用的网络活动,包括电子邮件和浏览数据。"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"您的个人应用已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。您的 VPN 提供商可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"打开 VPN 设置"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此设备由您的家长管理。您的家长可以查看和管理相关信息,例如您使用的应用、您的位置信息和设备使用时间。"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"在电池电量可能会耗尽时,系统会开启此模式"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"不用了"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"转储 SysUI 堆"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多个应用正在使用您的<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"广播名称"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"密码"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"保存"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"即将开始…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"无法广播"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 669cc3e..a9ae0f3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"請再嘗試拍攝螢幕擷取畫面"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"無法儲存螢幕截圖"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"應用程式或您的機構不允許擷取螢幕畫面"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"您的機構擁有此裝置,並可能會監察網絡流量"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」擁有此裝置,並可能會監察網絡流量"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"此裝置屬於您的機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連接至互聯網"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"此裝置屬於您的機構"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"此裝置屬於您的機構,並已透過 VPN 連接至互聯網"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過 VPN 連接至互聯網"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"您的機構可能監控您工作設定檔上的網絡流量"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>可能會監控您工作設定檔上的網絡流量"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理員可以查看工作設定檔的網絡活動"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"網絡可能會受到監控"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"此裝置已透過 VPN 連接至互聯網"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"您的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"您的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"此裝置由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 提供"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此裝置已安裝憑證授權單位。您的安全網絡流量可能會受監控或修改。"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"您的管理員已開啟網絡記錄功能,以監控您裝置上的流量。"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"您的管理員已開啟網絡記錄功能,可監控您工作設定檔 (而非個人設定檔) 的流量。"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連接至互聯網。IT 管理員可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"您的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員和 VPN 供應商可以看到您在工作應用程式的網絡活動,包括電郵和瀏覽資料。"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"您的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。您的 VPN 供應商可以看到您的網絡活動,包括電郵和瀏覽資料。"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"開啟 VPN 設定"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此裝置由您的家長管理。家長可以查看及管理裝置上的資料,例如您使用的應用程式、位置和裝置使用時間。"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"在電池電量可能耗盡前啟用「省電模式」"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"不用了,謝謝"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"廣播名稱"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"密碼"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"儲存"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"啟動中…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 6442e99..64b552b 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"請再次嘗試拍攝螢幕截圖"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"無法儲存螢幕截圖"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"這個應用程式或貴機構不允許擷取螢幕畫面"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,而且該機構可能會監控網路流量"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"這是「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」提供的裝置"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"這部裝置的擁有者為貴機構,並已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過「<xliff:g id="VPN_APP">%2$s</xliff:g>」連線到網際網路"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"這部裝置的擁有者為貴機構"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"這部裝置的擁有者為貴機構,並已透過 VPN 連線到網際網路"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」,並已透過 VPN 連線到網際網路"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"貴機構可能會監控你工作資料夾的網路流量"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"「<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>」可能會監控你工作資料夾的網路流量"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"IT 管理員可以查看工作資料夾的網路活動"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"網路可能會受到監控"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"這部裝置已透過 VPN 連線到網際網路"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"你的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"這部裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"這是「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」提供的裝置"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"裝置管理"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"這個裝置已安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"你的管理員已啟用網路記錄功能,可監控你裝置的流量。"</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"你的管理員已啟用網路記錄功能,可監控你的工作資料夾流量,但不會監控個人資料夾的流量。"</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"這部裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,IT 管理員可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"這部裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連線到網際網路。請注意,IT 管理員可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,IT 管理員和 VPN 供應商可以看見你在工作應用程式中的網路活動,包括電子郵件和瀏覽資料。"</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"你的個人應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,VPN 供應商可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"開啟 VPN 設定"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"這個裝置是由你的家長管理。家長可以查看及管理裝置上的資訊,例如你使用的應用程式、所在位置和裝置使用時間。"</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"在電池電量即將耗盡時開啟"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"不用了,謝謝"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"廣播名稱"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"密碼"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"儲存"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"啟動中…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9b7e203..05bb802 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -78,6 +78,8 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Zama ukuthatha isithombe-skrini futhi"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Ayikwazi ukulondoloza isithombe-skrini"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho"</string>
+ <!-- no translation found for screenshot_blocked_by_admin (5486757604822795797) -->
+ <skip />
<string name="screenshot_edit_label" msgid="8754981973544133050">"Hlela"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"Hlela isithombe-skrini"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"Yabelana ngesithombe-skrini"</string>
@@ -365,28 +367,20 @@
<string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
<string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
<string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Le divayisi ihlinzekwa yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_named_vpn (4137564460025113168) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (2169227918166358741) -->
- <skip />
+ <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Le divayisi ingeyenhlangano yakho futhi ixhunywe ku-inthanethi ngokusebenzisa i-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Le divayisi ingeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%2$s</xliff:g>"</string>
<string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Le divayisi eyenhlangano yakho"</string>
<string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>"</string>
- <!-- no translation found for quick_settings_disclosure_management_vpns (929181757984262902) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_management_vpns (3312645578322079185) -->
- <skip />
+ <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Le divayisi ingeyenhlangano yakho futhi ixhunywe ku-inthanethi ngama-VPN"</string>
+ <string name="quick_settings_disclosure_named_management_vpns" msgid="3312645578322079185">"Le divayisi ingeye-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> futhi ixhunywe ku-inthanethi ngama-VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Inhlangano yakho ingaqapha ithrafikhi yenethiwekhi kuphrofayela yakho yomsebenzi"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"I-<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> ingaqaphela ithrafikhi yenethiwekhi kuphrofayela yakho yomsebenzi"</string>
<string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Umsebenzi wenethiwekhi yephrofayela yomsebenzi uyabonakala kumphathi wakho we-IT"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Inethiwekhi kungenzeka iqashiwe"</string>
- <!-- no translation found for quick_settings_disclosure_vpns (3586175303518266301) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (153393105176944100) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (451254750289172191) -->
- <skip />
- <!-- no translation found for quick_settings_disclosure_named_vpn (6191822916936028208) -->
- <skip />
+ <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Le divayisi ixhunywe ku-inthanethi ngama-VPN"</string>
+ <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Ama-app akho omsebenzi axhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Ama-app akho womuntu siqu axhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+ <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Le divayisi ixhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="monitoring_title_financed_device" msgid="3659962357973919387">"Le divayisi ihlinzekwa yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"Ukuphathwa kwedivayisi"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"I-VPN"</string>
@@ -402,14 +396,10 @@
<string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ukugunyaza kwesitifiketi kufakwe kule divayisi. Ithrafikhi yenethiwekhi yakho evikelekile ingaqashelwa noma ilungiswe."</string>
<string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Umlawuli wakho uvule ukungena kwedivayisi yakho, okuqapha ithrafikhi kudivayisi yakho."</string>
<string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Umlawuli wakho uvule ukungena kwenethiwekhi, okuhlola ithrafikhi kudivayisi yakho yephrofayela yomsebenzi kodwa hhayi kuphrofayela yakho yomuntu siqu."</string>
- <!-- no translation found for monitoring_description_named_vpn (7502657784155456414) -->
- <skip />
- <!-- no translation found for monitoring_description_two_named_vpns (6726394451199620634) -->
- <skip />
- <!-- no translation found for monitoring_description_managed_profile_named_vpn (7254359257263069766) -->
- <skip />
- <!-- no translation found for monitoring_description_personal_profile_named_vpn (5083909710727365452) -->
- <skip />
+ <string name="monitoring_description_named_vpn" msgid="7502657784155456414">"Le divayisi ixhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>. Umsebenzi wakho wenethiwekhi, ohlanganisa ama-imeyili nedatha yokubhrawuza, ubonakala kumphathi wakho we-IT."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Le divayisi ixhunywe ku-inthanethi nge-<xliff:g id="VPN_APP_0">%1$s</xliff:g> nange-<xliff:g id="VPN_APP_1">%2$s</xliff:g>. Umsebenzi wakho wenethiwekhi, ohlanganisa ama-imeyili nedatha yokubhrawuza, ubonakala kumphathi wakho we-IT."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Ama-app akho okusebenza axhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>. Umsebenzi wakho wenethiwekhi kuma-app womsebenzi, okuhlanganisa ama-imeyili nedatha yokubhrawuza, ubonakala kumphathi wakho we-IT nomhlinzeki we-VPN."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Ama-app akho womuntu siqu axhunywe ku-inthanethi nge-<xliff:g id="VPN_APP">%1$s</xliff:g>. Umsebenzi wakho wenethiwekhi, okuhlanganisa ama-imeyili nedatha yokubhrawuza, ubonakala kumhlinzeki wakho we-VPN."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
<string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Vula izilungiselelo ze-VPN"</string>
<string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Le divayisi iphethwe ngumzali wakho. Umzali wakho angabona futhi aphathe ulwazi olunjengezinhlelo zokusebenza ozisebenzisayo, indawo yakho, kanye nesikhathi sesikrini."</string>
@@ -730,6 +720,8 @@
<string name="auto_saver_text" msgid="3214960308353838764">"Vula uma ibhethri sekungenzeka liphele"</string>
<string name="no_auto_saver_action" msgid="7467924389609773835">"Cha ngiyabonga"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"I-Dump SysUI Heap"</string>
+ <!-- no translation found for ongoing_privacy_dialog_a11y_title (2205794093673327974) -->
+ <skip />
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" kanye "</string>
@@ -855,9 +847,11 @@
<string name="media_output_broadcast_name" msgid="8786127091542624618">"Londoloza Igama"</string>
<string name="media_output_broadcast_code" msgid="870795639644728542">"Iphasiwedi"</string>
<string name="media_output_broadcast_dialog_save" msgid="7910865591430010198">"Londoloza"</string>
- <!-- no translation found for media_output_broadcast_starting (8130153654166235557) -->
+ <string name="media_output_broadcast_starting" msgid="8130153654166235557">"Iyaqala…"</string>
+ <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ayikwazi ukusakaza"</string>
+ <!-- no translation found for media_output_broadcast_update_error (1420868236079122521) -->
<skip />
- <!-- no translation found for media_output_broadcast_start_failed (3670835946856129775) -->
+ <!-- no translation found for media_output_broadcast_last_update_error (5484328807296895491) -->
<skip />
<string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
<string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f77430b..0bc3594 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -282,15 +282,12 @@
<!-- Spacing between chip icon and chip text -->
<dimen name="overlay_action_chip_spacing">8dp</dimen>
<dimen name="overlay_action_chip_text_size">14sp</dimen>
- <dimen name="overlay_offset_y">8dp</dimen>
<dimen name="overlay_offset_x">16dp</dimen>
- <dimen name="overlay_preview_elevation">4dp</dimen>
<dimen name="overlay_action_container_margin_horizontal">8dp</dimen>
<dimen name="overlay_bg_protection_height">242dp</dimen>
<dimen name="overlay_action_container_corner_radius">18dp</dimen>
<dimen name="overlay_action_container_padding_vertical">4dp</dimen>
<dimen name="overlay_action_container_padding_right">8dp</dimen>
- <dimen name="overlay_dismiss_button_elevation">7dp</dimen>
<dimen name="overlay_dismiss_button_tappable_size">48dp</dimen>
<dimen name="overlay_dismiss_button_margin">8dp</dimen>
<dimen name="overlay_border_width">4dp</dimen>
@@ -478,6 +475,22 @@
<dimen name="qqs_layout_margin_top">16dp</dimen>
<dimen name="qqs_layout_padding_bottom">24dp</dimen>
+ <!-- Most of the time it should be the same as notification_side_paddings as it's vertically
+ aligned with notifications. The exception is split shade when this value becomes
+ independent -->
+ <dimen name="qs_horizontal_margin">@dimen/notification_side_paddings</dimen>
+
+ <!-- Most of the time it should be the same as notification_shade_content_margin_horizontal as
+ it's vertically aligned with notifications. The exception is split shade when this value
+ becomes independent -->
+ <dimen name="qs_content_horizontal_padding">@dimen/notification_shade_content_margin_horizontal</dimen>
+
+ <!-- Most of the time it should be the same as notification_side_paddings as it's vertically
+ aligned with notifications. That's not the case on large screen when we have either split
+ shade and QS is not above notifications or in portrait shade when notification scrim is no
+ longer full width and next page of tiles should be at the edge of the screen -->
+ <dimen name="qs_tiles_page_horizontal_margin">@dimen/notification_side_paddings</dimen>
+
<dimen name="qs_customize_internal_side_paddings">8dp</dimen>
<dimen name="qs_icon_size">20dp</dimen>
<dimen name="qs_side_view_size">28dp</dimen>
@@ -1118,7 +1131,7 @@
<!-- Output switcher panel related dimensions -->
<dimen name="media_output_dialog_list_margin">12dp</dimen>
- <dimen name="media_output_dialog_list_max_height">364dp</dimen>
+ <dimen name="media_output_dialog_list_max_height">355dp</dimen>
<dimen name="media_output_dialog_header_album_icon_size">72dp</dimen>
<dimen name="media_output_dialog_header_back_icon_size">32dp</dimen>
<dimen name="media_output_dialog_header_icon_padding">16dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6cc61b4..2426f01 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1211,7 +1211,7 @@
<string name="wallet_app_button_label">Show all</string>
<!-- Label of the button underneath the card carousel prompting user unlock device. [CHAR LIMIT=NONE] -->
<!-- Secondary label of the quick access wallet tile if no card. [CHAR LIMIT=NONE] -->
- <string name="wallet_secondary_label_no_card">Add a card</string>
+ <string name="wallet_secondary_label_no_card">Tap to open</string>
<!-- Secondary label of the quick access wallet tile if wallet is still updating. [CHAR LIMIT=NONE] -->
<string name="wallet_secondary_label_updating">Updating</string>
<!-- Secondary label of the quick access wallet tile if device locked. [CHAR LIMIT=NONE] -->
@@ -2229,9 +2229,7 @@
<string name="media_move_closer_to_end_cast">Move closer to <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g> to play here</string>
<!-- Text informing the user that their media is now playing on a different device (deviceName). [CHAR LIMIT=50] -->
<string name="media_transfer_playing_different_device">Playing on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
- <!-- Text informing the user that their media is now playing on this device. [CHAR LIMIT=50] -->
- <string name="media_transfer_playing_this_device">Playing on this phone</string>
- <!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIMIT=50] -->
+ <!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIsMIT=50] -->
<string name="media_transfer_failed">Something went wrong. Try again.</string>
<!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
@@ -2484,6 +2482,8 @@
<string name="clipboard_edit_image_description">Edit copied image</string>
<!-- Label for button to send copied content to a nearby device [CHAR LIMIT=NONE] -->
<string name="clipboard_send_nearby_description">Send to nearby device</string>
+ <!-- Text informing user that copied content is hidden [CHAR LIMIT=NONE] -->
+ <string name="clipboard_text_hidden">Tap to view</string>
<!-- Generic "add" string [CHAR LIMIT=NONE] -->
<string name="add">Add</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index c93c065..0c25f54 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -380,7 +380,7 @@
<item name="android:buttonBarNegativeButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
<item name="android:buttonBarNeutralButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
<item name="android:colorBackground">?androidprv:attr/colorSurface</item>
- <item name="android:alertDialogStyle">@style/AlertDialogStyle</item>
+ <item name="android:alertDialogStyle">@style/ScrollableAlertDialogStyle</item>
<item name="android:buttonBarStyle">@style/ButtonBarStyle</item>
<item name="android:buttonBarButtonStyle">@style/Widget.Dialog.Button.Large</item>
</style>
@@ -389,6 +389,10 @@
<item name="android:layout">@layout/alert_dialog_systemui</item>
</style>
+ <style name="ScrollableAlertDialogStyle" parent="@androidprv:style/AlertDialog.DeviceDefault">
+ <item name="android:layout">@layout/scrollable_alert_dialog_systemui</item>
+ </style>
+
<style name="ButtonBarStyle" parent="@androidprv:style/DeviceDefault.ButtonBar.AlertDialog">
<item name="android:paddingTop">@dimen/dialog_button_bar_top_padding</item>
<item name="android:paddingBottom">@dimen/dialog_bottom_padding</item>
@@ -994,6 +998,7 @@
<style name="Theme.SystemUI.Dialog.Cast">
<item name="android:textAppearanceMedium">@style/TextAppearance.CastItem</item>
+ <item name="android:alertDialogStyle">@style/AlertDialogStyle</item>
</style>
<!-- ************************************************************************************* -->
@@ -1111,8 +1116,9 @@
</style>
<style name="FgsManagerAppDuration">
- <item name="android:fontFamily">?android:attr/textAppearanceSmall</item>
<item name="android:textDirection">locale</item>
+ <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="BroadcastDialog">
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index f195d20..38fa354 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -16,14 +16,20 @@
package com.android.keyguard
+import android.annotation.IntDef
import android.content.ContentResolver
import android.database.ContentObserver
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
+import android.util.Log
import com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
@@ -44,6 +50,20 @@
dumpManager: DumpManager
) : Dumpable {
+ companion object {
+ const val TAG = "ActiveUnlockConfig"
+
+ const val BIOMETRIC_TYPE_NONE = 0
+ const val BIOMETRIC_TYPE_ANY_FACE = 1
+ const val BIOMETRIC_TYPE_ANY_FINGERPRINT = 2
+ const val BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT = 3
+ }
+
+ @Retention(AnnotationRetention.SOURCE)
+ @IntDef(BIOMETRIC_TYPE_NONE, BIOMETRIC_TYPE_ANY_FACE, BIOMETRIC_TYPE_ANY_FINGERPRINT,
+ BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT)
+ annotation class BiometricType
+
/**
* Indicates the origin for an active unlock request.
*/
@@ -51,35 +71,50 @@
WAKE, UNLOCK_INTENT, BIOMETRIC_FAIL, ASSISTANT
}
+ var keyguardUpdateMonitor: KeyguardUpdateMonitor? = null
private var requestActiveUnlockOnWakeup = false
private var requestActiveUnlockOnUnlockIntent = false
private var requestActiveUnlockOnBioFail = false
+ private var faceErrorsToTriggerBiometricFailOn = mutableSetOf(FACE_ERROR_TIMEOUT)
+ private var faceAcquireInfoToTriggerBiometricFailOn = mutableSetOf<Int>()
+ private var onUnlockIntentWhenBiometricEnrolled = mutableSetOf<Int>(BIOMETRIC_TYPE_NONE)
+
private val settingsObserver = object : ContentObserver(handler) {
- private val wakeUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
- private val unlockIntentUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)
- private val bioFailUri: Uri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)
+ private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
+ private val unlockIntentUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)
+ private val bioFailUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)
+ private val faceErrorsUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS)
+ private val faceAcquireInfoUri =
+ secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)
+ private val unlockIntentWhenBiometricEnrolledUri =
+ secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
fun register() {
- contentResolver.registerContentObserver(
- wakeUri,
- false,
- this,
- UserHandle.USER_ALL)
- contentResolver.registerContentObserver(
- unlockIntentUri,
- false,
- this,
- UserHandle.USER_ALL)
- contentResolver.registerContentObserver(
- bioFailUri,
- false,
- this,
- UserHandle.USER_ALL)
+ registerUri(
+ listOf(
+ wakeUri,
+ unlockIntentUri,
+ bioFailUri,
+ faceErrorsUri,
+ faceAcquireInfoUri,
+ unlockIntentWhenBiometricEnrolledUri
+ )
+ )
onChange(true, ArrayList(), 0, getCurrentUser())
}
+ private fun registerUri(uris: Collection<Uri>) {
+ for (uri in uris) {
+ contentResolver.registerContentObserver(
+ uri,
+ false,
+ this,
+ UserHandle.USER_ALL)
+ }
+ }
+
override fun onChange(
selfChange: Boolean,
uris: Collection<Uri>,
@@ -104,6 +139,55 @@
requestActiveUnlockOnBioFail = secureSettings.getIntForUser(
ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, 0, getCurrentUser()) == 1
}
+
+ if (selfChange || uris.contains(faceErrorsUri)) {
+ processStringArray(
+ secureSettings.getStringForUser(ACTIVE_UNLOCK_ON_FACE_ERRORS,
+ getCurrentUser()),
+ faceErrorsToTriggerBiometricFailOn,
+ setOf(FACE_ERROR_TIMEOUT))
+ }
+
+ if (selfChange || uris.contains(faceAcquireInfoUri)) {
+ processStringArray(
+ secureSettings.getStringForUser(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
+ getCurrentUser()),
+ faceAcquireInfoToTriggerBiometricFailOn,
+ setOf<Int>())
+ }
+
+ if (selfChange || uris.contains(unlockIntentWhenBiometricEnrolledUri)) {
+ processStringArray(
+ secureSettings.getStringForUser(
+ ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+ getCurrentUser()),
+ onUnlockIntentWhenBiometricEnrolled,
+ setOf(BIOMETRIC_TYPE_NONE))
+ }
+ }
+
+ /**
+ * Convert a pipe-separated set of integers into a set of ints.
+ * @param stringSetting expected input are integers delineated by a pipe. For example,
+ * it may look something like this: "1|5|3".
+ * @param out updates the "out" Set will the integers between the pipes.
+ * @param default If stringSetting is null, "out" will be populated with values in "default"
+ */
+ private fun processStringArray(
+ stringSetting: String?,
+ out: MutableSet<Int>,
+ default: Set<Int>
+ ) {
+ out.clear()
+ stringSetting?.let {
+ for (code: String in stringSetting.split("|")) {
+ try {
+ out.add(code.toInt())
+ } catch (e: NumberFormatException) {
+ Log.e(TAG, "Passed an invalid setting=$code")
+ }
+ }
+ } ?: out.addAll(default)
}
}
@@ -113,6 +197,30 @@
}
/**
+ * If any active unlock triggers are enabled.
+ */
+ fun isActiveUnlockEnabled(): Boolean {
+ return requestActiveUnlockOnWakeup || requestActiveUnlockOnUnlockIntent ||
+ requestActiveUnlockOnBioFail
+ }
+
+ /**
+ * Whether the face error code from {@link BiometricFaceConstants} should trigger
+ * active unlock on biometric failure.
+ */
+ fun shouldRequestActiveUnlockOnFaceError(errorCode: Int): Boolean {
+ return faceErrorsToTriggerBiometricFailOn.contains(errorCode)
+ }
+
+ /**
+ * Whether the face acquireInfo from {@link BiometricFaceConstants} should trigger
+ * active unlock on biometric failure.
+ */
+ fun shouldRequestActiveUnlockOnFaceAcquireInfo(acquiredInfo: Int): Boolean {
+ return faceAcquireInfoToTriggerBiometricFailOn.contains(acquiredInfo)
+ }
+
+ /**
* Whether to trigger active unlock based on where the request is coming from and
* the current settings.
*/
@@ -121,7 +229,8 @@
ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE -> requestActiveUnlockOnWakeup
ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT ->
- requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup
+ requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup ||
+ (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL ->
requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntent ||
@@ -131,17 +240,55 @@
}
}
- /**
- * If any active unlock triggers are enabled.
- */
- fun isActiveUnlockEnabled(): Boolean {
- return requestActiveUnlockOnWakeup || requestActiveUnlockOnUnlockIntent ||
- requestActiveUnlockOnBioFail
+ private fun shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment(): Boolean {
+ if (!requestActiveUnlockOnBioFail) {
+ return false
+ }
+
+ keyguardUpdateMonitor?.let {
+ val anyFaceEnrolled = it.isFaceEnrolled
+ val anyFingerprintEnrolled =
+ it.getCachedIsUnlockWithFingerprintPossible(getCurrentUser())
+ val udfpsEnrolled = it.isUdfpsEnrolled
+
+ if (!anyFaceEnrolled && !anyFingerprintEnrolled) {
+ return onUnlockIntentWhenBiometricEnrolled.contains(BIOMETRIC_TYPE_NONE)
+ }
+
+ if (!anyFaceEnrolled && anyFingerprintEnrolled) {
+ return onUnlockIntentWhenBiometricEnrolled.contains(
+ BIOMETRIC_TYPE_ANY_FINGERPRINT) ||
+ (udfpsEnrolled && onUnlockIntentWhenBiometricEnrolled.contains(
+ BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT))
+ }
+
+ if (!anyFingerprintEnrolled && anyFaceEnrolled) {
+ return onUnlockIntentWhenBiometricEnrolled.contains(BIOMETRIC_TYPE_ANY_FACE)
+ }
+ }
+
+ return false
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
+ pw.println("Settings:")
pw.println(" requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup")
pw.println(" requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent")
pw.println(" requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail")
+ pw.println(" requestActiveUnlockOnUnlockIntentWhenBiometricEnrolled=" +
+ "$onUnlockIntentWhenBiometricEnrolled")
+ pw.println(" requestActiveUnlockOnFaceError=$faceErrorsToTriggerBiometricFailOn")
+ pw.println(" requestActiveUnlockOnFaceAcquireInfo=" +
+ "$faceAcquireInfoToTriggerBiometricFailOn")
+
+ pw.println("Current state:")
+ keyguardUpdateMonitor?.let {
+ pw.println(" shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment=" +
+ "${shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment()}")
+ pw.println(" faceEnrolled=${it.isFaceEnrolled}")
+ pw.println(" fpEnrolled=${
+ it.getCachedIsUnlockWithFingerprintPossible(getCurrentUser())}")
+ pw.println(" udfpsEnrolled=${it.isUdfpsEnrolled}")
+ } ?: pw.println(" keyguardUpdateMonitor is uninitialized")
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index 6a68c70..98ac640 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -28,7 +28,6 @@
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -169,7 +168,7 @@
private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
private final FalsingCollector mFalsingCollector;
private final DevicePostureController mDevicePostureController;
- private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final KeyguardViewController mKeyguardViewController;
@Inject
public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -181,7 +180,7 @@
TelephonyManager telephonyManager, FalsingCollector falsingCollector,
EmergencyButtonController.Factory emergencyButtonControllerFactory,
DevicePostureController devicePostureController,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ KeyguardViewController keyguardViewController) {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
@@ -194,7 +193,7 @@
mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
mFalsingCollector = falsingCollector;
mDevicePostureController = devicePostureController;
- mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ mKeyguardViewController = keyguardViewController;
}
/** Create a new {@link KeyguardInputViewController}. */
@@ -215,7 +214,7 @@
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mInputMethodManager, emergencyButtonController, mMainExecutor, mResources,
- mFalsingCollector, mStatusBarKeyguardViewManager);
+ mFalsingCollector, mKeyguardViewController);
} else if (keyguardInputView instanceof KeyguardPINView) {
return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 1903526..8f44e97 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -43,7 +43,6 @@
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
import java.util.List;
@@ -56,7 +55,7 @@
private final KeyguardSecurityCallback mKeyguardSecurityCallback;
private final InputMethodManager mInputMethodManager;
private final DelayableExecutor mMainExecutor;
- private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final KeyguardViewController mKeyguardViewController;
private final boolean mShowImeAtScreenOn;
private EditText mPasswordEntry;
private ImageView mSwitchImeButton;
@@ -119,14 +118,14 @@
@Main DelayableExecutor mainExecutor,
@Main Resources resources,
FalsingCollector falsingCollector,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ KeyguardViewController keyguardViewController) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, falsingCollector,
emergencyButtonController);
mKeyguardSecurityCallback = keyguardSecurityCallback;
mInputMethodManager = inputMethodManager;
mMainExecutor = mainExecutor;
- mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+ mKeyguardViewController = keyguardViewController;
mShowImeAtScreenOn = resources.getBoolean(R.bool.kg_show_ime_at_screen_on);
mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
mSwitchImeButton = mView.findViewById(R.id.switch_ime_button);
@@ -209,7 +208,7 @@
}
private void showInput() {
- if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ if (!mKeyguardViewController.isBouncerShowing()) {
return;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 41f9240..39c3949 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -282,7 +282,7 @@
super.reloadColors();
mMessageAreaController.reloadColors();
int textColor = Utils.getColorAttr(mLockPatternView.getContext(),
- android.R.attr.textColorPrimary).getDefaultColor();
+ android.R.attr.textColorSecondary).getDefaultColor();
int errorColor = Utils.getColorError(mLockPatternView.getContext()).getDefaultColor();
mLockPatternView.setColors(textColor, textColor, errorColor);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index bbe9a362..121ac29 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -56,7 +56,6 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
-import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -1615,7 +1614,7 @@
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
- if (errMsgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT) {
+ if (mActiveUnlockConfig.shouldRequestActiveUnlockOnFaceError(errMsgId)) {
requestActiveUnlock(
ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
"faceError-" + errMsgId);
@@ -1625,6 +1624,13 @@
@Override
public void onAuthenticationAcquired(int acquireInfo) {
handleFaceAcquired(acquireInfo);
+
+ if (mActiveUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
+ acquireInfo)) {
+ requestActiveUnlock(
+ ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
+ "faceAcquireInfo-" + acquireInfo);
+ }
}
};
@@ -1639,6 +1645,7 @@
private boolean mFingerprintLockedOut;
private boolean mFingerprintLockedOutPermanent;
private boolean mFaceLockedOutPermanent;
+ private HashMap<Integer, Boolean> mIsUnlockWithFingerprintPossible = new HashMap<>();
private TelephonyManager mTelephonyManager;
/**
@@ -1889,6 +1896,7 @@
dumpManager.registerDumpable(getClass().getName(), this);
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
mActiveUnlockConfig = activeUnlockConfiguration;
+ mActiveUnlockConfig.setKeyguardUpdateMonitor(this);
mHandler = new Handler(mainLooper) {
@Override
@@ -2329,7 +2337,7 @@
}
if (shouldTriggerActiveUnlock()) {
- if (DEBUG) {
+ if (DEBUG_ACTIVE_UNLOCK) {
Log.d("ActiveUnlock", "initiate active unlock triggerReason=" + reason);
}
mTrustManager.reportUserMayRequestUnlock(KeyguardUpdateMonitor.getCurrentUser());
@@ -2359,7 +2367,7 @@
}
if (allowRequest && shouldTriggerActiveUnlock()) {
- if (DEBUG) {
+ if (DEBUG_ACTIVE_UNLOCK) {
Log.d("ActiveUnlock", "reportUserRequestedUnlock"
+ " origin=" + requestOrigin.name()
+ " reason=" + reason
@@ -2777,8 +2785,17 @@
}
private boolean isUnlockWithFingerprintPossible(int userId) {
- return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
- && mFpm.hasEnrolledTemplates(userId);
+ mIsUnlockWithFingerprintPossible.put(userId, mFpm != null && mFpm.isHardwareDetected()
+ && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId));
+ return mIsUnlockWithFingerprintPossible.get(userId);
+ }
+
+ /**
+ * Cached value for whether fingerprint is enrolled and possible to use for authentication.
+ * Note: checking fingerprint enrollment directly with the AuthController requires an IPC.
+ */
+ public boolean getCachedIsUnlockWithFingerprintPossible(int userId) {
+ return mIsUnlockWithFingerprintPossible.get(userId);
}
private boolean isUnlockWithFacePossible(int userId) {
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index e191365..fdde402 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -55,7 +55,7 @@
@NonNull private final RectF mSensorRect;
@NonNull private PointF mLockIconCenter = new PointF(0f, 0f);
- private int mRadius;
+ private float mRadius;
private int mLockIconPadding;
private ImageView mLockIcon;
@@ -126,7 +126,7 @@
* Set the location of the lock icon.
*/
@VisibleForTesting
- public void setCenterLocation(@NonNull PointF center, int radius, int drawablePadding) {
+ public void setCenterLocation(@NonNull PointF center, float radius, int drawablePadding) {
mLockIconCenter = center;
mRadius = radius;
mLockIconPadding = drawablePadding;
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 2b217f0..d79b145 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -188,6 +188,7 @@
protected void onViewAttached() {
updateIsUdfpsEnrolled();
updateConfiguration();
+ updateLockIconLocation();
updateKeyguardShowing();
mUserUnlockedWithBiometric = false;
@@ -340,20 +341,17 @@
mHeightPixels = bounds.bottom;
mBottomPaddingPx = getResources().getDimensionPixelSize(R.dimen.lock_icon_margin_bottom);
- final int defaultPaddingPx =
- getResources().getDimensionPixelSize(R.dimen.lock_icon_padding);
- mScaledPaddingPx = (int) (defaultPaddingPx * mAuthController.getScaleFactor());
-
mUnlockedLabel = mView.getContext().getResources().getString(
R.string.accessibility_unlock_button);
mLockedLabel = mView.getContext()
.getResources().getString(R.string.accessibility_lock_icon);
-
- updateLockIconLocation();
}
private void updateLockIconLocation() {
if (mUdfpsSupported) {
+ final int defaultPaddingPx =
+ getResources().getDimensionPixelSize(R.dimen.lock_icon_padding);
+ mScaledPaddingPx = (int) (defaultPaddingPx * mAuthController.getScaleFactor());
mView.setCenterLocation(mAuthController.getUdfpsLocation(),
mAuthController.getUdfpsRadius(), mScaledPaddingPx);
} else {
@@ -362,8 +360,6 @@
mHeightPixels - mBottomPaddingPx - sLockIconRadiusPx),
sLockIconRadiusPx, mScaledPaddingPx);
}
-
- mView.getHitRect(mSensorTouchLocation);
}
@Override
@@ -386,6 +382,7 @@
pw.println(" mCanDismissLockScreen: " + mCanDismissLockScreen);
pw.println(" mStatusBarState: " + StatusBarState.toString(mStatusBarState));
pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);
+ pw.println(" mSensorTouchLocation: " + mSensorTouchLocation);
if (mView != null) {
mView.dump(pw, args);
@@ -672,6 +669,7 @@
}
private boolean inLockIconArea(MotionEvent event) {
+ mView.getHitRect(mSensorTouchLocation);
return mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
&& mView.getVisibility() == View.VISIBLE;
}
@@ -692,6 +690,7 @@
mExecutor.execute(() -> {
updateIsUdfpsEnrolled();
updateConfiguration();
+ updateLockIconLocation();
});
}
@@ -705,6 +704,11 @@
public void onEnrollmentsChanged() {
updateUdfpsConfig();
}
+
+ @Override
+ public void onUdfpsLocationChanged() {
+ updateLockIconLocation();
+ }
};
private final View.OnClickListener mA11yClickListener = v -> onLongPress();
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index caf7ee4..c91c899 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -30,7 +30,6 @@
import androidx.annotation.StyleRes;
-import com.android.settingslib.Utils;
import com.android.systemui.animation.Interpolators;
/**
@@ -42,24 +41,29 @@
private ValueAnimator mContractAnimator;
private AnimatorSet mContractAnimatorSet;
private GradientDrawable mBackground;
- private int mNormalColor;
- private int mHighlightColor;
- private int mStyle;
+ private Drawable mImageButton;
private TextView mDigitTextView;
+ private int mNormalBackgroundColor;
+ private int mPressedBackgroundColor;
+ private int mTextColorPrimary;
+ private int mTextColorPressed;
+ private int mStyle;
private static final int EXPAND_ANIMATION_MS = 100;
private static final int EXPAND_COLOR_ANIMATION_MS = 50;
private static final int CONTRACT_ANIMATION_DELAY_MS = 33;
private static final int CONTRACT_ANIMATION_MS = 417;
- NumPadAnimator(Context context, final Drawable drawable, @StyleRes int style) {
- this(context, drawable, style, null);
+ NumPadAnimator(Context context, final Drawable drawable,
+ @StyleRes int style, Drawable buttonImage) {
+ this(context, drawable, style, null, buttonImage);
}
NumPadAnimator(Context context, final Drawable drawable, @StyleRes int style,
- @Nullable TextView digitTextView) {
+ @Nullable TextView digitTextView, @Nullable Drawable buttonImage) {
mStyle = style;
mBackground = (GradientDrawable) drawable;
mDigitTextView = digitTextView;
+ mImageButton = buttonImage;
reloadColors(context);
}
@@ -88,26 +92,28 @@
* Reload colors from resources.
**/
void reloadColors(Context context) {
- int[] customAttrs = {android.R.attr.colorControlNormal,
- android.R.attr.colorControlHighlight};
+ boolean isNumPadKey = mImageButton == null;
+ int[] customAttrs = {android.R.attr.colorControlNormal};
ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
TypedArray a = ctw.obtainStyledAttributes(customAttrs);
- mNormalColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
+ mNormalBackgroundColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
com.android.internal.R.attr.colorSurface);
- mHighlightColor = a.getColor(1, 0);
a.recycle();
+ mBackground.setColor(mNormalBackgroundColor);
- mBackground.setColor(mNormalColor);
- createAnimators(context);
+ mPressedBackgroundColor = context.getColor(android.R.color.system_accent1_200);
+ mTextColorPrimary = isNumPadKey
+ ? com.android.settingslib.Utils
+ .getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+ : com.android.settingslib.Utils
+ .getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse);
+ mTextColorPressed = com.android.settingslib.Utils
+ .getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorOnAccent);
+ createAnimators();
}
- private void createAnimators(Context context) {
- int textColorPrimary = Utils.getColorAttrDefaultColor(context,
- android.R.attr.textColorPrimary);
- int textColorPrimaryInverse = Utils.getColorAttrDefaultColor(context,
- android.R.attr.textColorPrimaryInverse);
-
+ private void createAnimators() {
// Actual values will be updated later, usually during an onLayout() call
mExpandAnimator = ValueAnimator.ofFloat(0f, 1f);
mExpandAnimator.setDuration(EXPAND_ANIMATION_MS);
@@ -116,7 +122,7 @@
anim -> mBackground.setCornerRadius((float) anim.getAnimatedValue()));
ValueAnimator expandBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
- mNormalColor, mHighlightColor);
+ mNormalBackgroundColor, mPressedBackgroundColor);
expandBackgroundColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
expandBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
expandBackgroundColorAnimator.addUpdateListener(
@@ -124,13 +130,16 @@
ValueAnimator expandTextColorAnimator =
ValueAnimator.ofObject(new ArgbEvaluator(),
- textColorPrimary, textColorPrimaryInverse);
+ mTextColorPrimary, mTextColorPressed);
expandTextColorAnimator.setInterpolator(Interpolators.LINEAR);
expandTextColorAnimator.setDuration(EXPAND_COLOR_ANIMATION_MS);
expandTextColorAnimator.addUpdateListener(valueAnimator -> {
if (mDigitTextView != null) {
mDigitTextView.setTextColor((int) valueAnimator.getAnimatedValue());
}
+ if (mImageButton != null) {
+ mImageButton.setTint((int) valueAnimator.getAnimatedValue());
+ }
});
mExpandAnimatorSet = new AnimatorSet();
@@ -144,7 +153,7 @@
mContractAnimator.addUpdateListener(
anim -> mBackground.setCornerRadius((float) anim.getAnimatedValue()));
ValueAnimator contractBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
- mHighlightColor, mNormalColor);
+ mPressedBackgroundColor, mNormalBackgroundColor);
contractBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR);
contractBackgroundColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
contractBackgroundColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
@@ -152,8 +161,8 @@
animator -> mBackground.setColor((int) animator.getAnimatedValue()));
ValueAnimator contractTextColorAnimator =
- ValueAnimator.ofObject(new ArgbEvaluator(), textColorPrimaryInverse,
- textColorPrimary);
+ ValueAnimator.ofObject(new ArgbEvaluator(), mTextColorPressed,
+ mTextColorPrimary);
contractTextColorAnimator.setInterpolator(Interpolators.LINEAR);
contractTextColorAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
contractTextColorAnimator.setDuration(CONTRACT_ANIMATION_MS);
@@ -161,6 +170,9 @@
if (mDigitTextView != null) {
mDigitTextView.setTextColor((int) valueAnimator.getAnimatedValue());
}
+ if (mImageButton != null) {
+ mImageButton.setTint((int) valueAnimator.getAnimatedValue());
+ }
});
mContractAnimatorSet = new AnimatorSet();
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 7b98f27..8099f75 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -42,7 +42,7 @@
Drawable background = getBackground();
if (background instanceof GradientDrawable) {
mAnimator = new NumPadAnimator(context, background.mutate(),
- attrs.getStyleAttribute());
+ attrs.getStyleAttribute(), getDrawable());
} else {
mAnimator = null;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index f771c97..4aed251 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -134,7 +134,7 @@
Drawable background = getBackground();
if (background instanceof GradientDrawable) {
mAnimator = new NumPadAnimator(context, background.mutate(),
- R.style.NumPadKey, mDigitText);
+ R.style.NumPadKey, mDigitText, null);
} else {
mAnimator = null;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
index 6e06130..334bb1e 100644
--- a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
@@ -76,12 +76,6 @@
void playTrustedSound();
/**
- * When the bouncer is shown or hides
- * @param shown
- */
- void onBouncerVisiblityChanged(boolean shown);
-
- /**
* @return true if the screen is on
*/
boolean isScreenOn();
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 84b6ace..1270bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -56,7 +56,6 @@
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarOverlayController;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.plugins.ActivityStarter;
@@ -360,7 +359,6 @@
@Inject Lazy<ProtoTracer> mProtoTracer;
@Inject Lazy<MediaOutputDialogFactory> mMediaOutputDialogFactory;
@Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
- @Inject Lazy<NavigationBarOverlayController> mNavbarButtonsControllerLazy;
@Inject Lazy<TelephonyListenerManager> mTelephonyListenerManager;
@Inject Lazy<SystemStatusAnimationScheduler> mSystemStatusAnimationSchedulerLazy;
@Inject Lazy<PrivacyDotViewController> mPrivacyDotViewControllerLazy;
@@ -580,8 +578,6 @@
mProviders.put(MediaOutputDialogFactory.class, mMediaOutputDialogFactory::get);
- mProviders.put(NavigationBarOverlayController.class, mNavbarButtonsControllerLazy::get);
-
mProviders.put(SystemStatusAnimationScheduler.class,
mSystemStatusAnimationSchedulerLazy::get);
mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get);
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 8d65098..dd31218 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -47,6 +47,7 @@
import android.hardware.graphics.common.DisplayDecorationSupport;
import android.os.Handler;
import android.os.SystemProperties;
+import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.util.DisplayUtils;
@@ -899,8 +900,8 @@
final DisplayInfo displayInfo = new DisplayInfo();
mContext.getDisplay().getDisplayInfo(displayInfo);
return DisplayUtils.getPhysicalPixelDisplaySizeRatio(
- stableDisplaySize.x, stableDisplaySize.y, displayInfo.logicalWidth,
- displayInfo.logicalHeight);
+ stableDisplaySize.x, stableDisplaySize.y, displayInfo.getNaturalWidth(),
+ displayInfo.getNaturalHeight());
}
@Override
@@ -1067,15 +1068,22 @@
}
private void updateLayoutParams() {
- if (mOverlays == null) {
- return;
+ //ToDo: We should skip unnecessary call to update view layout.
+ Trace.beginSection("ScreenDecorations#updateLayoutParams");
+ if (mScreenDecorHwcWindow != null) {
+ mWindowManager.updateViewLayout(mScreenDecorHwcWindow, getHwcWindowLayoutParams());
}
- for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
- if (mOverlays[i] == null) {
- continue;
+
+ if (mOverlays != null) {
+ for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
+ if (mOverlays[i] == null) {
+ continue;
+ }
+ mWindowManager.updateViewLayout(
+ mOverlays[i].getRootView(), getWindowLayoutParams(i));
}
- mWindowManager.updateViewLayout(mOverlays[i].getRootView(), getWindowLayoutParams(i));
}
+ Trace.endSection();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
index f4f39a1..ca4b8ef 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
@@ -22,6 +22,8 @@
interface AlternateUdfpsTouchProvider {
/**
+ * onPointerDown:
+ *
* This operation is used to notify the Fingerprint HAL that
* a fingerprint has been detected on the device's screen.
*
@@ -39,4 +41,14 @@
* See fingerprint/ISession#onPointerUp for more details.
*/
fun onPointerUp(pointerId: Long)
+
+ /**
+ * onUiReady:
+ *
+ * This operation is used by the callee to notify the Fingerprint HAL that SystemUI is
+ * correctly configured for the fingerprint capture.
+ *
+ * See fingerprint/ISession#onUiReady for more details.
+ */
+ fun onUiReady()
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index d59ad92..75339aa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -79,6 +79,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import javax.inject.Inject;
@@ -278,6 +279,7 @@
}
});
mUdfpsController.setAuthControllerUpdateUdfpsLocation(this::updateUdfpsLocation);
+ mUdfpsController.setHalControlsIllumination(mUdfpsProps.get(0).halControlsIllumination);
mUdfpsBounds = mUdfpsProps.get(0).getLocation().getRect();
updateUdfpsLocation();
}
@@ -445,11 +447,11 @@
/**
* @return the radius of UDFPS on the screen in pixels
*/
- public int getUdfpsRadius() {
+ public float getUdfpsRadius() {
if (mUdfpsController == null || mUdfpsBounds == null) {
return -1;
}
- return mUdfpsBounds.height() / 2;
+ return mUdfpsBounds.height() / 2f;
}
/**
@@ -633,11 +635,17 @@
displayInfo.getNaturalHeight());
final FingerprintSensorPropertiesInternal udfpsProp = mUdfpsProps.get(0);
+ final Rect previousUdfpsBounds = mUdfpsBounds;
mUdfpsBounds = udfpsProp.getLocation().getRect();
mUdfpsBounds.scale(scaleFactor);
mUdfpsController.updateOverlayParams(udfpsProp.sensorId,
new UdfpsOverlayParams(mUdfpsBounds, displayInfo.getNaturalWidth(),
displayInfo.getNaturalHeight(), scaleFactor, displayInfo.rotation));
+ if (!Objects.equals(previousUdfpsBounds, mUdfpsBounds)) {
+ for (Callback cb : mCallbacks) {
+ cb.onUdfpsLocationChanged();
+ }
+ }
}
}
@@ -1053,5 +1061,10 @@
* Called when the biometric prompt is no longer showing.
*/
default void onBiometricPromptDismissed() {}
+
+ /**
+ * The location in pixels can change due to resolution changes.
+ */
+ default void onUdfpsLocationChanged() {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 76c1dbc..86e5016 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -80,6 +80,7 @@
@VisibleForTesting
internal var startLightRevealScrimOnKeyguardFadingAway = false
+ var lightRevealScrimAnimator: ValueAnimator? = null
var fingerprintSensorLocation: PointF? = null
private var faceSensorLocation: PointF? = null
private var circleReveal: LightRevealEffect? = null
@@ -163,7 +164,8 @@
if (keyguardStateController.isKeyguardFadingAway) {
val lightRevealScrim = centralSurfaces.lightRevealScrim
if (startLightRevealScrimOnKeyguardFadingAway && lightRevealScrim != null) {
- ValueAnimator.ofFloat(.1f, 1f).apply {
+ lightRevealScrimAnimator?.cancel()
+ lightRevealScrimAnimator = ValueAnimator.ofFloat(.1f, 1f).apply {
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
duration = RIPPLE_ANIMATION_DURATION
startDelay = keyguardStateController.keyguardFadingAwayDelay
@@ -183,6 +185,8 @@
if (lightRevealScrim.revealEffect == circleReveal) {
lightRevealScrim.revealEffect = LiftReveal
}
+
+ lightRevealScrimAnimator = null
}
})
start()
@@ -192,6 +196,13 @@
}
}
+ /**
+ * Whether we're animating the light reveal scrim from a call to [onKeyguardFadingAwayChanged].
+ */
+ fun isAnimatingLightRevealScrim(): Boolean {
+ return lightRevealScrimAnimator?.isRunning ?: false
+ }
+
override fun onStartedGoingToSleep() {
// reset the light reveal start in case we were pending an unlock
startLightRevealScrimOnKeyguardFadingAway = false
@@ -324,15 +335,17 @@
updateSensorLocation()
}
- override fun onEnrollmentsChanged() {
+ override fun onUdfpsLocationChanged() {
+ updateUdfpsDependentParams()
+ updateSensorLocation()
}
}
private fun updateUdfpsDependentParams() {
authController.udfpsProps?.let {
if (it.size > 0) {
- udfpsRadius = it[0].location.sensorRadius.toFloat()
udfpsController = udfpsControllerProvider.get()
+ udfpsRadius = authController.udfpsRadius
if (mView.isAttachedToWindow) {
udfpsController?.addCallback(udfpsControllerCallback)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 463db5c..a35f042 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -131,6 +131,7 @@
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting int mSensorId;
+ private boolean mHalControlsIllumination;
@VisibleForTesting @NonNull UdfpsOverlayParams mOverlayParams = new UdfpsOverlayParams();
// TODO(b/229290039): UDFPS controller should manage its dimensions on its own. Remove this.
@Nullable private Runnable mAuthControllerUpdateUdfpsLocation;
@@ -201,9 +202,10 @@
mKeyguardUpdateMonitor, mDialogManager, mDumpManager,
mLockscreenShadeTransitionController, mConfigurationController,
mSystemClock, mKeyguardStateController,
- mUnlockedScreenOffAnimationController, mHbmProvider, requestId, reason,
- callback, (view, event, fromUdfpsView) -> onTouch(requestId, event,
- fromUdfpsView), mActivityLaunchAnimator)));
+ mUnlockedScreenOffAnimationController, mHalControlsIllumination,
+ mHbmProvider, requestId, reason, callback,
+ (view, event, fromUdfpsView) -> onTouch(requestId, event,
+ fromUdfpsView), mActivityLaunchAnimator)));
}
@Override
@@ -310,6 +312,11 @@
mAuthControllerUpdateUdfpsLocation = r;
}
+ // TODO(b/229290039): UDFPS controller should manage its properties on its own. Remove this.
+ public void setHalControlsIllumination(boolean value) {
+ mHalControlsIllumination = value;
+ }
+
/**
* Calculate the pointer speed given a velocity tracker and the pointer id.
* This assumes that the velocity tracker has already been passed all relevant motion events.
@@ -813,7 +820,11 @@
final UdfpsView view = mOverlay.getOverlayView();
if (view != null) {
view.startIllumination(() -> {
- mFingerprintManager.onUiReady(requestId, mSensorId);
+ if (mAlternateTouchProvider != null) {
+ mAlternateTouchProvider.onUiReady();
+ } else {
+ mFingerprintManager.onUiReady(requestId, mSensorId);
+ }
mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 9c8aee4..2d51c97 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -77,6 +77,7 @@
private val systemClock: SystemClock,
private val keyguardStateController: KeyguardStateController,
private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
+ private val halControlsIllumination: Boolean,
private var hbmProvider: UdfpsHbmProvider,
val requestId: Long,
@ShowReason val requestReason: Int,
@@ -137,6 +138,7 @@
R.layout.udfps_view, null, false
) as UdfpsView).apply {
overlayParams = params
+ halControlsIllumination = this@UdfpsControllerOverlay.halControlsIllumination
setHbmProvider(hbmProvider)
val animation = inflateUdfpsAnimation(this, controller)
if (animation != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index 2f09792..8de7213 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -154,7 +154,9 @@
//re-calculate the height of description
View description = mView.findViewById(R.id.description);
- totalHeight += measureDescription(description, displayHeight, width, totalHeight);
+ if (description != null && description.getVisibility() != View.GONE) {
+ totalHeight += measureDescription(description, displayHeight, width, totalHeight);
+ }
return new AuthDialog.LayoutParams(width, totalHeight);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
index 38c937f..f26dd5f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHbmProvider.java
@@ -34,8 +34,11 @@
* invoked from the UI thread.
*
* @param onHbmEnabled A runnable that will be executed once HBM is enabled.
+ *
+ * TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
+ * This only makes sense now because vendor code may rely on the side effects of enableHbm.
*/
- void enableHbm(@Nullable Runnable onHbmEnabled);
+ void enableHbm(boolean halControlsIllumination, @Nullable Runnable onHbmEnabled);
/**
* UdfpsView will call this to disable HBM when illumination is no longer needed.
@@ -46,8 +49,6 @@
* The call must be made from the UI thread. The callback, if provided, will also be invoked
* from the UI thread.
*
- *
- *
* @param onHbmDisabled A runnable that will be executed once HBM is disabled.
*/
void disableHbm(@Nullable Runnable onHbmDisabled);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 9139699..f28fedb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -32,6 +32,7 @@
import android.view.ViewGroup;
import android.widget.ImageView;
+import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
@@ -44,6 +45,8 @@
import com.airbnb.lottie.model.KeyPath;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* View corresponding with udfps_keyguard_view.xml
@@ -52,7 +55,6 @@
private UdfpsDrawable mFingerprintDrawable; // placeholder
private LottieAnimationView mAodFp;
private LottieAnimationView mLockScreenFp;
- private int mStatusBarState;
// used when highlighting fp icon:
private int mTextColorPrimary;
@@ -70,7 +72,7 @@
private float mBurnInOffsetY;
private float mBurnInProgress;
private float mInterpolatedDarkAmount;
- private boolean mAnimatingBetweenAodAndLockscreen; // As opposed to Unlocked => AOD
+ private int mAnimationType = ANIMATION_NONE;
private boolean mFullyInflated;
public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
@@ -117,8 +119,10 @@
return;
}
- final float darkAmountForAnimation = mAnimatingBetweenAodAndLockscreen
- ? mInterpolatedDarkAmount : 1f /* animating from unlocked to AOD */;
+ // if we're animating from screen off, we can immediately place the icon in the
+ // AoD-burn in location, else we need to translate the icon from LS => AoD.
+ final float darkAmountForAnimation = mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF
+ ? 1f : mInterpolatedDarkAmount;
mBurnInOffsetX = MathUtils.lerp(0f,
getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
- mMaxBurnInOffsetX, darkAmountForAnimation);
@@ -127,12 +131,12 @@
- mMaxBurnInOffsetY, darkAmountForAnimation);
mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation);
- if (mAnimatingBetweenAodAndLockscreen && !mPauseAuth) {
+ if (mAnimationType == ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN && !mPauseAuth) {
mLockScreenFp.setTranslationX(mBurnInOffsetX);
mLockScreenFp.setTranslationY(mBurnInOffsetY);
mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
- } else if (mInterpolatedDarkAmount == 0f) {
+ } else if (darkAmountForAnimation == 0f) {
mLockScreenFp.setTranslationX(0);
mLockScreenFp.setTranslationY(0);
mBgProtection.setAlpha(mAlpha / 255f);
@@ -148,9 +152,15 @@
mAodFp.setProgress(mBurnInProgress);
mAodFp.setAlpha(mInterpolatedDarkAmount);
- // done animating between AoD & LS
- if (mInterpolatedDarkAmount == 1f || mInterpolatedDarkAmount == 0f) {
- mAnimatingBetweenAodAndLockscreen = false;
+ // done animating
+ final boolean doneAnimatingBetweenAodAndLS =
+ mAnimationType == ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN
+ && (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f);
+ final boolean doneAnimatingUnlockedScreenOff =
+ mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF
+ && (mInterpolatedDarkAmount == 1f);
+ if (doneAnimatingBetweenAodAndLS || doneAnimatingUnlockedScreenOff) {
+ mAnimationType = ANIMATION_NONE;
}
}
@@ -158,10 +168,6 @@
mUdfpsRequested = request;
}
- void setStatusBarState(int statusBarState) {
- mStatusBarState = statusBarState;
- }
-
void updateColor() {
if (!mFullyInflated) {
return;
@@ -219,8 +225,16 @@
return mAlpha;
}
- void onDozeAmountChanged(float linear, float eased, boolean animatingBetweenAodAndLockscreen) {
- mAnimatingBetweenAodAndLockscreen = animatingBetweenAodAndLockscreen;
+ static final int ANIMATION_NONE = 0;
+ static final int ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN = 1;
+ static final int ANIMATION_UNLOCKED_SCREEN_OFF = 2;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ANIMATION_NONE, ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN, ANIMATION_UNLOCKED_SCREEN_OFF})
+ private @interface AnimationType {}
+
+ void onDozeAmountChanged(float linear, float eased, @AnimationType int animationType) {
+ mAnimationType = animationType;
mInterpolatedDarkAmount = eased;
updateAlpha();
}
@@ -262,7 +276,7 @@
pw.println(" mUnpausedAlpha=" + getUnpausedAlpha());
pw.println(" mUdfpsRequested=" + mUdfpsRequested);
pw.println(" mInterpolatedDarkAmount=" + mInterpolatedDarkAmount);
- pw.println(" mAnimatingBetweenAodAndLockscreen=" + mAnimatingBetweenAodAndLockscreen);
+ pw.println(" mAnimationType=" + mAnimationType);
}
private final AsyncLayoutInflater.OnInflateFinishedListener mLayoutInflaterFinishListener =
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 8b0f36f..ec4cf2f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -121,7 +121,7 @@
mView.onDozeAmountChanged(
animation.getAnimatedFraction(),
(float) animation.getAnimatedValue(),
- /* animatingBetweenAodAndLockScreen */ false);
+ UdfpsKeyguardView.ANIMATION_UNLOCKED_SCREEN_OFF);
}
});
}
@@ -394,7 +394,7 @@
mUnlockedScreenOffDozeAnimator.start();
} else {
mView.onDozeAmountChanged(linear, eased,
- /* animatingBetweenAodAndLockScreen */ true);
+ UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN);
}
mLastDozeAmount = linear;
@@ -404,7 +404,6 @@
@Override
public void onStateChanged(int statusBarState) {
mStatusBarState = statusBarState;
- mView.setStatusBarState(statusBarState);
updateAlpha();
updatePauseAuth();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 2aa345a..245c225 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -63,9 +63,12 @@
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
var animationViewController: UdfpsAnimationViewController<*>? = null
- /** Parameters that affect the position and size of the overlay. Visible for testing. */
+ /** Parameters that affect the position and size of the overlay. */
var overlayParams = UdfpsOverlayParams()
+ /** Whether the HAL is responsible for enabling and disabling of LHBM. */
+ var halControlsIllumination: Boolean = true
+
/** Debug message. */
var debugMessage: String? = null
set(value) {
@@ -154,11 +157,17 @@
}
private fun doIlluminate(onIlluminatedRunnable: Runnable?) {
- hbmProvider?.enableHbm() {
+ // TODO(b/231335067): enableHbm with halControlsIllumination=true shouldn't make sense.
+ // This only makes sense now because vendor code may rely on the side effects of enableHbm.
+ hbmProvider?.enableHbm(halControlsIllumination) {
if (onIlluminatedRunnable != null) {
- // No framework API can reliably tell when a frame reaches the panel. A timeout
- // is the safest solution.
- postDelayed(onIlluminatedRunnable, onIlluminatedDelayMs)
+ if (halControlsIllumination) {
+ onIlluminatedRunnable.run()
+ } else {
+ // No framework API can reliably tell when a frame reaches the panel. A timeout
+ // is the safest solution.
+ postDelayed(onIlluminatedRunnable, onIlluminatedDelayMs)
+ }
} else {
Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null")
}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index bd67a7f..ee8363f 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -38,6 +38,7 @@
import android.app.RemoteAction;
import android.content.BroadcastReceiver;
import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -107,6 +108,8 @@
public static final String SELF_PERMISSION = "com.android.systemui.permission.SELF";
public static final String COPY_OVERLAY_ACTION = "com.android.systemui.COPY";
+ private static final String EXTRA_EDIT_SOURCE_CLIPBOARD = "edit_source_clipboard";
+
private static final int CLIPBOARD_DEFAULT_TIMEOUT_MILLIS = 6000;
private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe
@@ -126,6 +129,8 @@
private final View mClipboardPreview;
private final ImageView mImagePreview;
private final TextView mTextPreview;
+ private final TextView mHiddenTextPreview;
+ private final TextView mHiddenImagePreview;
private final View mPreviewBorder;
private final OverlayActionChip mEditChip;
private final OverlayActionChip mRemoteCopyChip;
@@ -184,6 +189,8 @@
mClipboardPreview = requireNonNull(mView.findViewById(R.id.clipboard_preview));
mImagePreview = requireNonNull(mView.findViewById(R.id.image_preview));
mTextPreview = requireNonNull(mView.findViewById(R.id.text_preview));
+ mHiddenTextPreview = requireNonNull(mView.findViewById(R.id.hidden_text_preview));
+ mHiddenImagePreview = requireNonNull(mView.findViewById(R.id.hidden_image_preview));
mPreviewBorder = requireNonNull(mView.findViewById(R.id.preview_border));
mEditChip = requireNonNull(mView.findViewById(R.id.edit_chip));
mRemoteCopyChip = requireNonNull(mView.findViewById(R.id.remote_copy_chip));
@@ -268,21 +275,32 @@
mExitAnimator.cancel();
}
reset();
+
+ boolean isSensitive = clipData != null && clipData.getDescription().getExtras() != null
+ && clipData.getDescription().getExtras()
+ .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE);
if (clipData == null || clipData.getItemCount() == 0) {
- showTextPreview(mContext.getResources().getString(
- R.string.clipboard_overlay_text_copied));
+ showTextPreview(
+ mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
+ mTextPreview);
} else if (!TextUtils.isEmpty(clipData.getItemAt(0).getText())) {
ClipData.Item item = clipData.getItemAt(0);
if (item.getTextLinks() != null) {
AsyncTask.execute(() -> classifyText(clipData.getItemAt(0), clipSource));
}
- showEditableText(item.getText());
+ if (isSensitive) {
+ showEditableText(
+ mContext.getResources().getString(R.string.clipboard_text_hidden), true);
+ } else {
+ showEditableText(item.getText(), false);
+ }
} else if (clipData.getItemAt(0).getUri() != null) {
// How to handle non-image URIs?
- showEditableImage(clipData.getItemAt(0).getUri());
+ showEditableImage(clipData.getItemAt(0).getUri(), isSensitive);
} else {
showTextPreview(
- mContext.getResources().getString(R.string.clipboard_overlay_text_copied));
+ mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
+ mTextPreview);
}
Intent remoteCopyIntent = getRemoteCopyIntent(clipData);
// Only show remote copy if it's available.
@@ -391,6 +409,7 @@
editIntent.setDataAndType(uri, "image/*");
editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ editIntent.putExtra(EXTRA_EDIT_SOURCE_CLIPBOARD, true);
mContext.startActivity(editIntent);
animateOut();
}
@@ -403,15 +422,23 @@
animateOut();
}
- private void showTextPreview(CharSequence text) {
- mTextPreview.setVisibility(View.VISIBLE);
+ private void showSinglePreview(View v) {
+ mTextPreview.setVisibility(View.GONE);
mImagePreview.setVisibility(View.GONE);
- mTextPreview.setText(text.subSequence(0, Math.min(500, text.length())));
+ mHiddenTextPreview.setVisibility(View.GONE);
+ mHiddenImagePreview.setVisibility(View.GONE);
+ v.setVisibility(View.VISIBLE);
+ }
+
+ private void showTextPreview(CharSequence text, TextView textView) {
+ showSinglePreview(textView);
+ textView.setText(text.subSequence(0, Math.min(500, text.length())));
mEditChip.setVisibility(View.GONE);
}
- private void showEditableText(CharSequence text) {
- showTextPreview(text);
+ private void showEditableText(CharSequence text, boolean hidden) {
+ TextView textView = hidden ? mHiddenTextPreview : mTextPreview;
+ showTextPreview(text, textView);
mEditChip.setVisibility(View.VISIBLE);
mActionContainerBackground.setVisibility(View.VISIBLE);
mEditChip.setAlpha(1f);
@@ -419,32 +446,36 @@
mContext.getString(R.string.clipboard_edit_text_description));
View.OnClickListener listener = v -> editText();
mEditChip.setOnClickListener(listener);
- mTextPreview.setOnClickListener(listener);
+ textView.setOnClickListener(listener);
}
- private void showEditableImage(Uri uri) {
- ContentResolver resolver = mContext.getContentResolver();
- try {
- int size = mContext.getResources().getDimensionPixelSize(R.dimen.overlay_x_scale);
- // The width of the view is capped, height maintains aspect ratio, so allow it to be
- // taller if needed.
- Bitmap thumbnail = resolver.loadThumbnail(uri, new Size(size, size * 4), null);
- mImagePreview.setImageBitmap(thumbnail);
- } catch (IOException e) {
- Log.e(TAG, "Thumbnail loading failed", e);
- showTextPreview(
- mContext.getResources().getString(R.string.clipboard_overlay_text_copied));
- return;
- }
- mTextPreview.setVisibility(View.GONE);
- mImagePreview.setVisibility(View.VISIBLE);
+ private void showEditableImage(Uri uri, boolean isSensitive) {
mEditChip.setAlpha(1f);
mActionContainerBackground.setVisibility(View.VISIBLE);
View.OnClickListener listener = v -> editImage(uri);
+ if (isSensitive) {
+ showSinglePreview(mHiddenImagePreview);
+ mHiddenImagePreview.setOnClickListener(listener);
+ } else {
+ showSinglePreview(mImagePreview);
+ ContentResolver resolver = mContext.getContentResolver();
+ try {
+ int size = mContext.getResources().getDimensionPixelSize(R.dimen.overlay_x_scale);
+ // The width of the view is capped, height maintains aspect ratio, so allow it to be
+ // taller if needed.
+ Bitmap thumbnail = resolver.loadThumbnail(uri, new Size(size, size * 4), null);
+ mImagePreview.setImageBitmap(thumbnail);
+ } catch (IOException e) {
+ Log.e(TAG, "Thumbnail loading failed", e);
+ showTextPreview(
+ mContext.getResources().getString(R.string.clipboard_overlay_text_copied),
+ mTextPreview);
+ }
+ mImagePreview.setOnClickListener(listener);
+ }
mEditChip.setOnClickListener(listener);
mEditChip.setContentDescription(
mContext.getString(R.string.clipboard_edit_image_description));
- mImagePreview.setOnClickListener(listener);
}
private Intent getRemoteCopyIntent(ClipData clipData) {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index 0d89879..b54b832 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -20,10 +20,12 @@
import android.app.Activity;
import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
@@ -41,6 +43,7 @@
private EditText mEditText;
private ClipboardManager mClipboardManager;
private TextView mAttribution;
+ private boolean mSensitive;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -72,6 +75,9 @@
}
mEditText.setText(clip.getItemAt(0).getText());
mEditText.requestFocus();
+ mSensitive = clip.getDescription().getExtras() != null
+ && clip.getDescription().getExtras()
+ .getBoolean(ClipDescription.EXTRA_IS_SENSITIVE);
mClipboardManager.addPrimaryClipChangedListener(this);
}
@@ -88,6 +94,9 @@
private void saveToClipboard() {
ClipData clip = ClipData.newPlainText("text", mEditText.getText());
+ PersistableBundle extras = new PersistableBundle();
+ extras.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, mSensitive);
+ clip.getDescription().setExtras(extras);
mClipboardManager.setPrimaryClip(clip);
hideImeAndFinish();
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index f9115b2..3eb58bb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -343,7 +343,7 @@
info.className = Switch::class.java.name
}
- override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
+ override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
if (super.performAccessibilityAction(host, action, args)) {
return true
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
rename to packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 5d154c3..4e48a52 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -38,7 +38,6 @@
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
-import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.qs.dagger.QSModule;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
@@ -80,8 +79,19 @@
import dagger.Provides;
/**
- * A dagger module for injecting default implementations of components of System UI that may be
- * overridden by the System UI implementation.
+ * A dagger module for injecting default implementations of components of System UI.
+ *
+ * Variants of SystemUI should make a copy of this, include it in their component, and customize it
+ * as needed.
+ *
+ * This module might alternatively be named `AospSystemUIModule`, `PhoneSystemUIModule`,
+ * or `BasicSystemUIModule`.
+ *
+ * Nothing in the module should be strictly required. Each piece should either be swappable with
+ * a different implementation or entirely removable.
+ *
+ * This is different from {@link SystemUIModule} which should be used for pieces of required
+ * SystemUI code that variants of SystemUI _must_ include to function correctly.
*/
@Module(includes = {
MediaModule.class,
@@ -90,7 +100,7 @@
StartCentralSurfacesModule.class,
VolumeModule.class
})
-public abstract class SystemUIDefaultModule {
+public abstract class ReferenceSystemUIModule {
@SysUISingleton
@Provides
@@ -101,9 +111,6 @@
}
@Binds
- abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
-
- @Binds
abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
@@ -148,6 +155,7 @@
return spC;
}
+ /** */
@Binds
@SysUISingleton
public abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 701972a..5d34a69 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -73,7 +73,7 @@
SystemUIBinder.class,
SystemUIModule.class,
SystemUICoreStartableModule.class,
- SystemUIDefaultModule.class})
+ ReferenceSystemUIModule.class})
public interface SysUIComponent {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index bbeb66c..535eff8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -100,8 +100,14 @@
import dagger.Provides;
/**
- * A dagger module for injecting components of System UI that are not overridden by the System UI
- * implementation.
+ * A dagger module for injecting components of System UI that are required by System UI.
+ *
+ * If your feature can be excluded, subclassed, or re-implemented by a variant of SystemUI, put
+ * your Dagger Module in {@link ReferenceSystemUIModule} and/or any variant modules that
+ * rely on the feature.
+ *
+ * Adding an entry in this file means that _all_ variants of SystemUI will receive that code. They
+ * may not appreciate that.
*/
@Module(includes = {
AppOpsModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 74044e2..1cc5df5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -39,7 +39,6 @@
import com.android.systemui.doze.DozeMachine.State;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.Assert;
@@ -94,7 +93,6 @@
private final AuthController mAuthController;
private final DelayableExecutor mMainExecutor;
private final KeyguardStateController mKeyguardStateController;
- private final BatteryController mBatteryController;
private final UiEventLogger mUiEventLogger;
private final DevicePostureController mDevicePostureController;
@@ -186,8 +184,7 @@
@Main DelayableExecutor mainExecutor,
UiEventLogger uiEventLogger,
KeyguardStateController keyguardStateController,
- DevicePostureController devicePostureController,
- BatteryController batteryController) {
+ DevicePostureController devicePostureController) {
mContext = context;
mDozeHost = dozeHost;
mConfig = config;
@@ -208,7 +205,6 @@
mMainExecutor = mainExecutor;
mUiEventLogger = uiEventLogger;
mKeyguardStateController = keyguardStateController;
- mBatteryController = batteryController;
}
private final DevicePostureController.Callback mDevicePostureCallback =
posture -> {
@@ -320,12 +316,7 @@
gentleWakeUp(pulseReason);
} else if (isPickup) {
if (shouldDropPickupEvent()) {
- mDozeLog.traceSensorEventDropped(
- pulseReason,
- "keyguardOccluded="
- + mKeyguardStateController.isOccluded()
- + " pluggedInWireless="
- + mBatteryController.isPluggedInWireless());
+ mDozeLog.traceSensorEventDropped(pulseReason, "keyguard occluded");
return;
}
gentleWakeUp(pulseReason);
@@ -356,7 +347,7 @@
}
private boolean shouldDropPickupEvent() {
- return mKeyguardStateController.isOccluded() || mBatteryController.isPluggedInWireless();
+ return mKeyguardStateController.isOccluded();
}
private void gentleWakeUp(int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index fb09132..14a7e3c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -44,6 +44,7 @@
import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController
import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController
import com.android.systemui.shared.system.smartspace.SmartspaceState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.policy.KeyguardStateController
import dagger.Lazy
@@ -140,7 +141,8 @@
keyguardViewMediator: Lazy<KeyguardViewMediator>,
private val keyguardViewController: KeyguardViewController,
private val featureFlags: FeatureFlags,
- private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>
+ private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>,
+ private val statusBarStateController: SysuiStatusBarStateController
) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() {
interface KeyguardUnlockAnimationListener {
@@ -372,7 +374,8 @@
* changed.
*/
override fun onKeyguardGoingAwayChanged() {
- if (keyguardStateController.isKeyguardGoingAway) {
+ if (keyguardStateController.isKeyguardGoingAway
+ && !statusBarStateController.leaveOpenOnKeyguardHide()) {
prepareForInWindowLauncherAnimations()
}
}
@@ -813,6 +816,11 @@
return false
}
+ // The smartspace is not visible if the bouncer is showing, so don't shared element it.
+ if (keyguardStateController.isBouncerShowing) {
+ return false
+ }
+
// We started to swipe to dismiss, but now we're doing a fling animation to complete the
// dismiss. In this case, the smartspace swiped away with the rest of the keyguard, so don't
// do the shared element transition.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 10ea1e0..4d59f1a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -779,16 +779,6 @@
}
@Override
- public void onBouncerVisiblityChanged(boolean shown) {
- synchronized (KeyguardViewMediator.this) {
- if (shown) {
- mPendingPinLock = false;
- }
- adjustStatusBarLocked(shown, false);
- }
- }
-
- @Override
public void playTrustedSound() {
KeyguardViewMediator.this.playTrustedSound();
}
@@ -921,12 +911,12 @@
RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+ setOccluded(false /* isOccluded */, true /* animate */);
+
if (apps == null || apps.length == 0 || apps[0] == null) {
Log.d(TAG, "No apps provided to unocclude runner; "
+ "skipping animation and unoccluding.");
-
finishedCallback.onAnimationFinished();
- setOccluded(false /* isOccluded */, true /* animate */);
return;
}
@@ -971,7 +961,6 @@
@Override
public void onAnimationEnd(Animator animation) {
try {
- setOccluded(false /* isOccluded */, true /* animate */);
finishedCallback.onAnimationFinished();
mUnoccludeAnimator = null;
} catch (RemoteException e) {
@@ -989,6 +978,19 @@
private DozeParameters mDozeParameters;
private final KeyguardStateController mKeyguardStateController;
+ private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onBouncerShowingChanged() {
+ synchronized (KeyguardViewMediator.this) {
+ if (mKeyguardStateController.isBouncerShowing()) {
+ mPendingPinLock = false;
+ }
+ adjustStatusBarLocked(mKeyguardStateController.isBouncerShowing(), false);
+ }
+ }
+ };
+
private final Lazy<KeyguardUnlockAnimationController> mKeyguardUnlockAnimationControllerLazy;
private final InteractionJankMonitor mInteractionJankMonitor;
private boolean mWallpaperSupportsAmbientMode;
@@ -1059,6 +1061,7 @@
statusBarStateController.addCallback(this);
mKeyguardStateController = keyguardStateController;
+ keyguardStateController.addCallback(mKeyguardStateControllerCallback);
mKeyguardUnlockAnimationControllerLazy = keyguardUnlockAnimationControllerLazy;
mScreenOffAnimationController = screenOffAnimationController;
mInteractionJankMonitor = interactionJankMonitor;
diff --git a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
index f93ce37..6e84238 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
@@ -21,6 +21,7 @@
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.ColorStateList
+import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.RippleDrawable
import com.android.internal.R
@@ -37,13 +38,6 @@
fun updateColorScheme(scheme: ColorScheme?)
}
-/** A generic implementation of [ColorTransition] so that we can define a factory method. */
-open class GenericColorTransition(
- private val applyTheme: (ColorScheme?) -> Unit
-) : ColorTransition {
- override fun updateColorScheme(scheme: ColorScheme?) = applyTheme(scheme)
-}
-
/**
* A [ColorTransition] that animates between two specific colors.
* It uses a ValueAnimator to execute the animation and interpolate between the source color and
@@ -96,7 +90,6 @@
typealias AnimatingColorTransitionFactory =
(Int, (ColorScheme) -> Int, (Int) -> Unit) -> AnimatingColorTransition
-typealias GenericColorTransitionFactory = ((ColorScheme?) -> Unit) -> GenericColorTransition
/**
* ColorSchemeTransition constructs a ColorTransition for each color in the scheme
@@ -105,23 +98,22 @@
*/
class ColorSchemeTransition internal constructor(
private val context: Context,
- mediaViewHolder: MediaViewHolder,
- animatingColorTransitionFactory: AnimatingColorTransitionFactory,
- genericColorTransitionFactory: GenericColorTransitionFactory
+ private val mediaViewHolder: MediaViewHolder,
+ animatingColorTransitionFactory: AnimatingColorTransitionFactory
) {
constructor(context: Context, mediaViewHolder: MediaViewHolder) :
- this(context, mediaViewHolder, ::AnimatingColorTransition, ::GenericColorTransition)
+ this(context, mediaViewHolder, ::AnimatingColorTransition)
+ private var isGradientEnabled = true
val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95)
-
val surfaceColor = animatingColorTransitionFactory(
bgColor,
::surfaceFromScheme
) { surfaceColor ->
val colorList = ColorStateList.valueOf(surfaceColor)
- mediaViewHolder.player.backgroundTintList = colorList
mediaViewHolder.seamlessIcon.imageTintList = colorList
mediaViewHolder.seamlessText.setTextColor(surfaceColor)
+ mediaViewHolder.albumView.backgroundTintList = colorList
mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor)
}
@@ -181,36 +173,15 @@
mediaViewHolder.seekBar.progressBackgroundTintList = ColorStateList.valueOf(textTertiary)
}
- // Note: This background gradient currently doesn't animate between colors.
- val backgroundGradient = genericColorTransitionFactory { scheme ->
- val defaultTintColor = ColorStateList.valueOf(bgColor)
- if (scheme == null) {
- mediaViewHolder.albumView.foregroundTintList = defaultTintColor
- mediaViewHolder.albumView.backgroundTintList = defaultTintColor
- return@genericColorTransitionFactory
- }
+ val bgGradientStart = animatingColorTransitionFactory(
+ bgColor,
+ albumGradientPicker(::backgroundStartFromScheme, 0.25f)
+ ) { _ -> updateAlbumGradient() }
- // If there's no album art, just hide the gradient so we show the solid background.
- val showGradient = mediaViewHolder.albumView.drawable != null
- val startColor = getColorWithAlpha(
- backgroundStartFromScheme(scheme),
- alpha = if (showGradient) .25f else 0f
- )
- val endColor = getColorWithAlpha(
- backgroundEndFromScheme(scheme),
- alpha = if (showGradient) .90f else 0f
- )
- val gradientColors = intArrayOf(startColor, endColor)
-
- val foregroundGradient = mediaViewHolder.albumView.foreground?.mutate()
- if (foregroundGradient is GradientDrawable) {
- foregroundGradient.colors = gradientColors
- }
- val backgroundGradient = mediaViewHolder.albumView.background?.mutate()
- if (backgroundGradient is GradientDrawable) {
- backgroundGradient.colors = gradientColors
- }
- }
+ val bgGradientEnd = animatingColorTransitionFactory(
+ bgColor,
+ albumGradientPicker(::backgroundEndFromScheme, 0.9f)
+ ) { _ -> updateAlbumGradient() }
val colorTransitions = arrayOf(
surfaceColor,
@@ -220,14 +191,37 @@
textPrimaryInverse,
textSecondary,
textTertiary,
- backgroundGradient
+ bgGradientStart,
+ bgGradientEnd
)
+ private fun updateAlbumGradient() {
+ val gradient = mediaViewHolder.albumView.foreground?.mutate()
+ if (gradient is GradientDrawable) {
+ gradient.colors = intArrayOf(
+ bgGradientStart?.currentColor ?: 0,
+ bgGradientEnd?.currentColor ?: 0)
+ }
+ }
+
+ private fun albumGradientPicker(
+ inner: (ColorScheme) -> Int,
+ targetAlpha: Float
+ ): (ColorScheme) -> Int {
+ return { scheme ->
+ if (isGradientEnabled)
+ getColorWithAlpha(inner(scheme), targetAlpha)
+ else
+ Color.TRANSPARENT
+ }
+ }
+
private fun loadDefaultColor(id: Int): Int {
return Utils.getColorAttr(context, id).defaultColor
}
- fun updateColorScheme(colorScheme: ColorScheme?) {
+ fun updateColorScheme(colorScheme: ColorScheme?, enableGradient: Boolean) {
+ isGradientEnabled = enableGradient
colorTransitions.forEach { it.updateColorScheme(colorScheme) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 38128bf..3483bc3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -926,17 +926,16 @@
val isSsReactivated: Boolean = false
)
- private val comparator =
- compareByDescending<MediaSortKey> { it.data.isPlaying == true &&
- it.data.playbackLocation == MediaData.PLAYBACK_LOCAL }
- .thenByDescending { it.data.isPlaying == true &&
- it.data.playbackLocation == MediaData.PLAYBACK_CAST_LOCAL
- }
- .thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
- .thenByDescending { !it.data.resumption }
- .thenByDescending { it.data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE }
- .thenByDescending { it.updateTime }
- .thenByDescending { it.data.notificationKey }
+ private val comparator = compareByDescending<MediaSortKey> {
+ it.data.isPlaying == true && it.data.playbackLocation == MediaData.PLAYBACK_LOCAL }
+ .thenByDescending {
+ it.data.isPlaying == true && it.data.playbackLocation == MediaData.PLAYBACK_CAST_LOCAL }
+ .thenByDescending { it.data.active }
+ .thenByDescending { shouldPrioritizeSs == it.isSsMediaRec }
+ .thenByDescending { !it.data.resumption }
+ .thenByDescending { it.data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE }
+ .thenByDescending { it.updateTime }
+ .thenByDescending { it.data.notificationKey }
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 20417af..8c2cb6d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -48,6 +48,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
@@ -96,7 +97,7 @@
* A view controller used for Media Playback.
*/
public class MediaControlPanel {
- private static final String TAG = "MediaControlPanel";
+ protected static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
private static final String EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME = "com.google"
@@ -105,7 +106,7 @@
"com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
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";
+ protected 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;
@@ -148,6 +149,7 @@
private RecommendationViewHolder mRecommendationViewHolder;
private String mKey;
private MediaData mMediaData;
+ private SmartspaceMediaData mRecommendationData;
private MediaViewController mMediaViewController;
private MediaSession.Token mToken;
private MediaController mController;
@@ -340,6 +342,10 @@
}
});
+ // AlbumView uses a hardware layer so that clipping of the foreground is handled
+ // with clipping the album art. Otherwise album art shows through at the edges.
+ mMediaViewHolder.getAlbumView().setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
TextView titleText = mMediaViewHolder.getTitleText();
TextView artistText = mMediaViewHolder.getArtistText();
AnimatorSet enter = loadAnimator(R.anim.media_metadata_enter,
@@ -443,6 +449,7 @@
bindOutputSwitcherChip(data);
bindGutsMenuForPlayer(data);
+ bindPlayerContentDescription(data);
bindScrubbingTime(data);
bindActionButtons(data);
@@ -536,12 +543,6 @@
}
private boolean bindSongMetadata(MediaData data) {
- // Accessibility label
- mMediaViewHolder.getPlayer().setContentDescription(
- mContext.getString(
- R.string.controls_media_playing_item_description,
- data.getSong(), data.getArtist(), data.getApp()));
-
TextView titleText = mMediaViewHolder.getTitleText();
TextView artistText = mMediaViewHolder.getArtistText();
return mMetadataAnimationHandler.setNext(
@@ -563,6 +564,48 @@
});
}
+ // We may want to look into unifying this with bindRecommendationContentDescription if/when we
+ // do a refactor of this class.
+ private void bindPlayerContentDescription(MediaData data) {
+ if (mMediaViewHolder == null) {
+ return;
+ }
+
+ CharSequence contentDescription;
+ if (mMediaViewController.isGutsVisible()) {
+ contentDescription = mMediaViewHolder.getGutsViewHolder().getGutsText().getText();
+ } else if (data != null) {
+ contentDescription = mContext.getString(
+ R.string.controls_media_playing_item_description,
+ data.getSong(),
+ data.getArtist(),
+ data.getApp());
+ } else {
+ contentDescription = null;
+ }
+ mMediaViewHolder.getPlayer().setContentDescription(contentDescription);
+ }
+
+ private void bindRecommendationContentDescription(SmartspaceMediaData data) {
+ if (mRecommendationViewHolder == null) {
+ return;
+ }
+
+ CharSequence contentDescription;
+ if (mMediaViewController.isGutsVisible()) {
+ contentDescription =
+ mRecommendationViewHolder.getGutsViewHolder().getGutsText().getText();
+ } else if (data != null) {
+ contentDescription = mContext.getString(
+ R.string.controls_media_smartspace_rec_description,
+ data.getAppName(mContext));
+ } else {
+ contentDescription = null;
+ }
+
+ mRecommendationViewHolder.getRecommendations().setContentDescription(contentDescription);
+ }
+
private void bindArtworkAndColors(MediaData data, boolean updateBackground) {
final int reqId = mArtworkNextBindRequestId++;
if (updateBackground) {
@@ -570,8 +613,8 @@
}
// Capture width & height from views in foreground for artwork scaling in background
- int width = mMediaViewHolder.getPlayer().getWidth();
- int height = mMediaViewHolder.getPlayer().getHeight();
+ int width = mMediaViewHolder.getAlbumView().getMeasuredWidth();
+ int height = mMediaViewHolder.getAlbumView().getMeasuredHeight();
// WallpaperColors.fromBitmap takes a good amount of time. We do that work
// on the background executor to avoid stalling animations on the UI Thread.
@@ -609,7 +652,6 @@
// Bind the album view to the artwork or a transition drawable
ImageView albumView = mMediaViewHolder.getAlbumView();
albumView.setPadding(0, 0, 0, 0);
- albumView.setClipToOutline(true);
if (updateBackground || (!mIsArtworkBound && isArtworkBound)) {
if (mPrevArtwork == null) {
albumView.setImageDrawable(artwork);
@@ -619,6 +661,12 @@
// the metadata changes).
TransitionDrawable transitionDrawable = new TransitionDrawable(
new Drawable[]{mPrevArtwork, artwork});
+
+ scaleTransitionDrawableLayer(transitionDrawable, 0, width, height);
+ scaleTransitionDrawableLayer(transitionDrawable, 1, width, height);
+ transitionDrawable.setLayerGravity(0, Gravity.CENTER);
+ transitionDrawable.setLayerGravity(1, Gravity.CENTER);
+
albumView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(isArtworkBound ? 333 : 80);
}
@@ -626,8 +674,12 @@
mIsArtworkBound = isArtworkBound;
}
+ // Scrim bounds are set manually so it scales as expected
+ albumView.getForeground().setBounds(0, 0,
+ Math.max(width, height), Math.max(width, height));
+
// Transition Colors to current color scheme
- mColorSchemeTransition.updateColorScheme(colorScheme);
+ mColorSchemeTransition.updateColorScheme(colorScheme, mIsArtworkBound);
// App icon - use notification icon
ImageView appIconView = mMediaViewHolder.getAppIcon();
@@ -652,6 +704,30 @@
});
}
+ private void scaleTransitionDrawableLayer(TransitionDrawable transitionDrawable, int layer,
+ int targetWidth, int targetHeight) {
+ Drawable drawable = transitionDrawable.getDrawable(layer);
+ if (drawable == null) {
+ return;
+ }
+
+ int width = drawable.getIntrinsicWidth();
+ int height = drawable.getIntrinsicHeight();
+ if (width == 0 || height == 0 || targetWidth == 0 || targetHeight == 0) {
+ return;
+ }
+
+ float scale;
+ if ((width / (float) height) > (targetWidth / (float) targetHeight)) {
+ // Drawable is wider than target view, scale to match height
+ scale = targetHeight / (float) height;
+ } else {
+ // Drawable is taller than target view, scale to match width
+ scale = targetWidth / (float) width;
+ }
+ transitionDrawable.setLayerSize(layer, (int) (scale * width), (int) (scale * height));
+ }
+
private void bindActionButtons(MediaData data) {
MediaButton semanticActions = data.getSemanticActions();
@@ -894,7 +970,7 @@
InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER) {
@Override
protected float getCurrentTopCornerRadius() {
- return ((IlluminationDrawable) player.getBackground()).getCornerRadius();
+ return mContext.getResources().getDimension(R.dimen.notification_corner_radius);
}
@Override
@@ -902,20 +978,6 @@
// TODO(b/184121838): Make IlluminationDrawable support top and bottom radius.
return getCurrentTopCornerRadius();
}
-
- @Override
- protected void setBackgroundCornerRadius(Drawable background, float topCornerRadius,
- float bottomCornerRadius) {
- // TODO(b/184121838): Make IlluminationDrawable support top and bottom radius.
- float radius = Math.min(topCornerRadius, bottomCornerRadius);
- ((IlluminationDrawable) background).setCornerRadiusOverride(radius);
- }
-
- @Override
- public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
- super.onLaunchAnimationEnd(isExpandingFullyAbove);
- ((IlluminationDrawable) player.getBackground()).setCornerRadiusOverride(null);
- }
};
}
@@ -930,6 +992,7 @@
return;
}
+ mRecommendationData = data;
mSmartspaceId = SmallHash.hash(data.getTargetId());
mPackageName = data.getPackageName();
mInstanceId = data.getInstanceId();
@@ -945,6 +1008,12 @@
return;
}
+ CharSequence appName = data.getAppName(mContext);
+ if (appName == null) {
+ Log.w(TAG, "Fail to get media recommendation's app name");
+ return;
+ }
+
PackageManager packageManager = mContext.getPackageManager();
// Set up media source app's logo.
Drawable icon = packageManager.getApplicationIcon(applicationInfo);
@@ -952,28 +1021,11 @@
headerLogoImageView.setImageDrawable(icon);
fetchAndUpdateRecommendationColors(icon);
- // Set up media source app's label text.
- 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 up media rec card's tap action if applicable.
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
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, appName));
+ bindRecommendationContentDescription(data);
List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
@@ -1155,6 +1207,11 @@
mRecommendationViewHolder.marquee(false, mMediaViewController.GUTS_ANIMATION_DURATION);
}
mMediaViewController.closeGuts(immediate);
+ if (mMediaViewHolder != null) {
+ bindPlayerContentDescription(mMediaData);
+ } else if (mRecommendationViewHolder != null) {
+ bindRecommendationContentDescription(mRecommendationData);
+ }
}
private void closeGuts() {
@@ -1168,6 +1225,11 @@
mRecommendationViewHolder.marquee(true, mMediaViewController.GUTS_ANIMATION_DURATION);
}
mMediaViewController.openGuts();
+ if (mMediaViewHolder != null) {
+ bindPlayerContentDescription(mMediaData);
+ } else if (mRecommendationViewHolder != null) {
+ bindRecommendationContentDescription(mRecommendationData);
+ }
mLogger.logLongPressOpen(mUid, mPackageName, mInstanceId);
}
@@ -1282,17 +1344,6 @@
});
}
- /** 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/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index f85078c..11ee657 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -30,6 +30,7 @@
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory
+import com.android.systemui.statusbar.policy.ConfigurationController
import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -44,6 +45,7 @@
private val localMediaManagerFactory: LocalMediaManagerFactory,
private val mr2manager: MediaRouter2Manager,
private val muteAwaitConnectionManagerFactory: MediaMuteAwaitConnectionManagerFactory,
+ private val configurationController: ConfigurationController,
@Main private val fgExecutor: Executor,
@Background private val bgExecutor: Executor,
dumpManager: DumpManager
@@ -79,7 +81,7 @@
oldEntry?.stop()
}
var entry = entries[key]
- if (entry == null || entry?.token != data.token) {
+ if (entry == null || entry.token != data.token) {
entry?.stop()
if (data.device != null) {
// If we were already provided device info (e.g. from RCN), keep that and don't
@@ -118,10 +120,9 @@
override fun dump(pw: PrintWriter, args: Array<String>) {
with(pw) {
println("MediaDeviceManager state:")
- entries.forEach {
- key, entry ->
+ entries.forEach { (key, entry) ->
println(" key=$key")
- entry.dump(pw, args)
+ entry.dump(pw)
}
}
}
@@ -165,6 +166,12 @@
// expected to connect imminently, it should be displayed as the current device.
private var aboutToConnectDeviceOverride: AboutToConnectDevice? = null
+ private val configListener = object : ConfigurationController.ConfigurationListener {
+ override fun onLocaleListChanged() {
+ updateCurrent()
+ }
+ }
+
@AnyThread
fun start() = bgExecutor.execute {
localMediaManager.registerCallback(this)
@@ -174,6 +181,7 @@
controller?.registerCallback(this)
updateCurrent()
started = true
+ configurationController.addCallback(configListener)
}
@AnyThread
@@ -183,9 +191,10 @@
localMediaManager.stopScan()
localMediaManager.unregisterCallback(this)
muteAwaitConnectionManager?.stopListening()
+ configurationController.removeCallback(configListener)
}
- fun dump(pw: PrintWriter, args: Array<String>) {
+ fun dump(pw: PrintWriter) {
val routingSession = controller?.let {
mr2manager.getRoutingSessionForMediaController(it)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 1437c96..7eccb3b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -278,13 +278,14 @@
/**
* Apply squishFraction to a copy of viewState such that the cached version is untouched.
*/
- private fun squishViewState(
+ @VisibleForTesting
+ internal fun squishViewState(
viewState: TransitionViewState,
squishFraction: Float
): TransitionViewState {
val squishedViewState = viewState.copy()
squishedViewState.height = (squishedViewState.height * squishFraction).toInt()
- val albumArtViewState = viewState.widgetStates.get(R.id.album_art)
+ val albumArtViewState = squishedViewState.widgetStates.get(R.id.album_art)
if (albumArtViewState != null) {
albumArtViewState.height = squishedViewState.height
}
@@ -317,6 +318,7 @@
if (transitionLayout == null) {
return null
}
+
// Not cached. Let's create a new measurement
if (state.expansion == 0.0f || state.expansion == 1.0f) {
result = transitionLayout!!.calculateViewState(
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
index 5c93cda..fc9515c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
@@ -69,23 +69,6 @@
val actionsTopBarrier = itemView.requireViewById<Barrier>(R.id.media_action_barrier_top)
- init {
- (player.background as IlluminationDrawable).let {
- it.registerLightSource(seamless)
- it.registerLightSource(gutsViewHolder.cancel)
- it.registerLightSource(gutsViewHolder.dismiss)
- it.registerLightSource(gutsViewHolder.settings)
- it.registerLightSource(actionPlayPause)
- it.registerLightSource(actionNext)
- it.registerLightSource(actionPrev)
- it.registerLightSource(action0)
- it.registerLightSource(action1)
- it.registerLightSource(action2)
- it.registerLightSource(action3)
- it.registerLightSource(action4)
- }
- }
-
fun getAction(id: Int): ImageButton {
return when (id) {
R.id.actionPlayPause -> actionPlayPause
@@ -161,7 +144,6 @@
R.id.media_scrubbing_total_time
)
-
// Buttons used for notification-based actions
val genericButtonIds = setOf(
R.id.action0,
diff --git a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
index 50a96f6..c8f17d9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
@@ -17,8 +17,13 @@
package com.android.systemui.media
import android.app.smartspace.SmartspaceAction
+import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
+import android.text.TextUtils
+import android.util.Log
import com.android.internal.logging.InstanceId
+import com.android.systemui.media.MediaControlPanel.KEY_SMARTSPACE_APP_NAME
/** State of a Smartspace media recommendations view. */
data class SmartspaceMediaData(
@@ -67,6 +72,32 @@
* Returns the list of [recommendations] that have valid data.
*/
fun getValidRecommendations() = recommendations.filter { it.icon != null }
+
+ /** Returns the upstream app name if available. */
+ fun getAppName(context: Context): CharSequence? {
+ val nameFromAction = cardAction?.intent?.extras?.getString(KEY_SMARTSPACE_APP_NAME)
+ if (!TextUtils.isEmpty(nameFromAction)) {
+ return nameFromAction
+ }
+
+ val packageManager = context.packageManager
+ packageManager.getLaunchIntentForPackage(packageName)?.let {
+ val launchActivity = it.resolveActivityInfo(packageManager, 0)
+ return launchActivity.loadLabel(packageManager)
+ }
+
+ Log.w(
+ TAG,
+ "Package $packageName does not have a main launcher activity. " +
+ "Fallback to full app name")
+ return try {
+ val applicationInfo = packageManager.getApplicationInfo(packageName, /* flags= */ 0)
+ packageManager.getApplicationLabel(applicationInfo)
+ } catch (e: PackageManager.NameNotFoundException) {
+ null
+ }
+ }
}
const val NUM_REQUIRED_RECOMMENDATIONS = 3
+private val TAG = SmartspaceMediaData::class.simpleName!!
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index a397f32..58a35ff 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -143,6 +143,7 @@
if (mController.isTransferring()) {
if (device.getState() == MediaDeviceState.STATE_CONNECTING
&& !mController.hasAdjustVolumeUserRestriction()) {
+ setUpDeviceIcon(device);
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
mController.getColorItemContent(),
@@ -151,11 +152,13 @@
false /* showSeekBar*/,
true /* showProgressBar */, false /* showStatus */);
} else {
+ setUpDeviceIcon(device);
setSingleLineLayout(getItemTitle(device), false /* bFocused */);
}
} else {
// Set different layout for each device
if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
+ setUpDeviceIcon(device);
mTitleText.setAlpha(DEVICE_CONNECTED_ALPHA);
mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA);
mStatusIcon.setImageDrawable(
@@ -167,6 +170,7 @@
mSubTitleText.setText(R.string.media_output_dialog_connect_failed);
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
} else if (device.getState() == MediaDeviceState.STATE_GROUPING) {
+ setUpDeviceIcon(device);
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
mController.getColorItemContent(),
@@ -176,7 +180,12 @@
true /* showProgressBar */, false /* showStatus */);
} else if (mController.getSelectedMediaDevice().size() > 1
&& isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
+ boolean isDeviceDeselectable = isDeviceIncluded(
+ mController.getDeselectableMediaDevice(), device);
mTitleText.setTextColor(mController.getColorItemContent());
+ mTitleIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.media_output_icon_volume));
+ mTitleIcon.setColorFilter(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
@@ -184,13 +193,20 @@
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(true);
- mCheckBox.setOnCheckedChangeListener(
- (buttonView, isChecked) -> onGroupActionTriggered(false, device));
+ mCheckBox.setOnCheckedChangeListener(isDeviceDeselectable
+ ? (buttonView, isChecked) -> onGroupActionTriggered(false, device)
+ : null);
+ mCheckBox.setEnabled(isDeviceDeselectable);
+ mCheckBox.setAlpha(
+ isDeviceDeselectable ? DEVICE_CONNECTED_ALPHA
+ : DEVICE_DISCONNECTED_ALPHA
+ );
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
initSeekbar(device, isCurrentSeekbarInvisible);
mEndTouchArea.setVisibility(View.VISIBLE);
mEndTouchArea.setOnClickListener(null);
- mEndTouchArea.setOnClickListener((v) -> mCheckBox.performClick());
+ mEndTouchArea.setOnClickListener(
+ isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null);
mEndTouchArea.setImportantForAccessibility(
View.IMPORTANT_FOR_ACCESSIBILITY_YES);
setUpContentDescriptionForView(mEndTouchArea, true, device);
@@ -198,6 +214,9 @@
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_check));
mStatusIcon.setColorFilter(mController.getColorItemContent());
+ mTitleIcon.setImageDrawable(
+ mContext.getDrawable(R.drawable.media_output_icon_volume));
+ mTitleIcon.setColorFilter(mController.getColorItemContent());
mTitleText.setTextColor(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
@@ -206,6 +225,7 @@
setUpContentDescriptionForView(mContainerLayout, false, device);
mCurrentActivePosition = position;
} else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+ setUpDeviceIcon(device);
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(false);
@@ -218,6 +238,7 @@
false /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
} else {
+ setUpDeviceIcon(device);
setSingleLineLayout(getItemTitle(device), false /* bFocused */);
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 5c2cc0b..b407e76f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -166,15 +166,6 @@
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
mDeviceId = device.getId();
- ThreadUtils.postOnBackgroundThread(() -> {
- Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext);
- ThreadUtils.postOnMainThread(() -> {
- if (!TextUtils.equals(mDeviceId, device.getId())) {
- return;
- }
- mTitleIcon.setImageIcon(icon);
- });
- });
}
abstract void onBind(int customizedItem, boolean topMargin, boolean bottomMargin);
@@ -414,5 +405,17 @@
mSeekBar.setEnabled(false);
mSeekBar.setOnTouchListener((v, event) -> true);
}
+
+ protected void setUpDeviceIcon(MediaDevice device) {
+ ThreadUtils.postOnBackgroundThread(() -> {
+ Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext);
+ ThreadUtils.postOnMainThread(() -> {
+ if (!TextUtils.equals(mDeviceId, device.getId())) {
+ return;
+ }
+ mTitleIcon.setImageIcon(icon);
+ });
+ });
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 5bb6557..8dcca3d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -449,7 +449,7 @@
abstract int getStopButtonVisibility();
public CharSequence getStopButtonText() {
- return mContext.getText(R.string.keyboard_key_media_stop);
+ return mContext.getText(R.string.media_output_dialog_button_stop_casting);
}
public void onStopButtonClick() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index e7f97d2..58b6ad3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -55,8 +55,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.drawable.IconCompat;
-import androidx.mediarouter.media.MediaRouter;
-import androidx.mediarouter.media.MediaRouterParams;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.Utils;
@@ -215,9 +213,8 @@
}
boolean shouldShowLaunchSection() {
- MediaRouterParams routerParams = MediaRouter.getInstance(mContext).getRouterParams();
- Log.d(TAG, "try to get routerParams: " + routerParams);
- return routerParams != null && !routerParams.isMediaTransferReceiverEnabled();
+ // TODO(b/231398073): Implements this when available.
+ return false;
}
void setRefreshing(boolean refreshing) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 9248433..026a305 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -104,7 +104,7 @@
@Override
public CharSequence getStopButtonText() {
- int resId = R.string.keyboard_key_media_stop;
+ int resId = R.string.media_output_dialog_button_stop_casting;
if (isBroadcastSupported() && mMediaOutputController.isPlaying()
&& !mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
resId = R.string.media_output_broadcast;
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
index 1145891..6379960 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
@@ -1,11 +1,43 @@
# Media Tap-To-Transfer
+## Overview
This package (and child packages) include code for the media tap-to-transfer feature, which
allows users to easily transfer playing media between devices.
-In media transfer, there are two devices: the *sender* and the *receiver*. The sender device will
-start and stop media casts to the receiver device. On both devices, System UI will display a chip
-informing the user about the media cast occurring.
+In media transfer, there are two devices: the **sender** and the **receiver**. The sender device
+will start and stop media casts to the receiver device. On both devices, System UI will display a
+chip informing the user about the media cast occurring.
-This package is structured so that the sender code is in the sender package, the receiver code is
-in the receiver package, and code that's shared between them is in the common package.
+**Important**: System UI is **not responsible** for performing the media transfer. System UI
+**only** displays an informational chip; external clients are responsible for performing the media
+transfer and informing System UI about the transfer status.
+
+## Information flow
+External clients notify System UI about the transfer status by calling `@SystemApi`s in
+`StatusBarManager`. For the sender device, use the `updateMediaTapToTransferSenderDisplay` API; for
+the receiver, use the `updateMediaTapToTransferReceiverDisplay` API. The APIs eventually flow into
+SystemUI's `CommandQueue`, which then notifies callbacks about the new state.
+`MediaTttChipControllerSender` implements the sender callback, and `MediaTttChipControllerReceiver`
+implements the receiver callback. These controllers will then show or hide the tap-to-transfer chip
+(depending on what information was sent in the API).
+
+## Architecture
+This package is structured so that the sender code is in the `sender` package, the receiver code is
+in the `receiver` package, and code that's shared between them is in the `common` package.
+
+* The `ChipStateSender` and `ChipStateReceiver` classes are enums that describe all the possible
+ transfer states (transfer started, transfer succeeded, etc.) and include relevant parameters for
+ each state.
+* The `ChipSenderInfo` and `ChipReceiverInfo` classes are simple data classes that contain all the
+ information needed to display a chip. They include the transfer state, information about the media
+ being transferred, etc.
+* The `MediaTttChipControllerSender` and `MediaTttChipControllerReceiver` classes are responsible
+ for showing or hiding the chip and updating the chip view based on information from the
+ `ChipInfo`. `MediaTttChipControllerCommon` has all the common logic for adding and removing the
+ view to the window and also includes any display logic that can be shared between the sender and
+ receiver. The sender and receiver controller subclasses have the display logic that's specific to
+ just the sender or just the receiver.
+
+## Testing
+If you want to test out the tap-to-transfer chip without using the `@SystemApi`s, you can use adb
+commands instead. Refer to `MediaTttCommandLineHelper` for information about adb commands.
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 357ff38..3c373f4 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -70,6 +70,7 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.Region;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -91,6 +92,8 @@
import android.view.Surface;
import android.view.View;
import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
+import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.WindowInsetsController.Appearance;
import android.view.WindowInsetsController.Behavior;
import android.view.WindowManager;
@@ -121,10 +124,12 @@
import com.android.systemui.navigationbar.buttons.DeadZone;
import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.navigationbar.buttons.RotationContextButton;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
@@ -152,6 +157,7 @@
import java.io.PrintWriter;
import java.util.Locale;
+import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
@@ -198,12 +204,14 @@
private final Optional<Recents> mRecentsOptional;
private final DeviceConfigProxy mDeviceConfigProxy;
private final NavigationBarTransitions mNavigationBarTransitions;
+ private final EdgeBackGestureHandler mEdgeBackGestureHandler;
private final Optional<BackAnimation> mBackAnimation;
private final Handler mHandler;
- private final NavigationBarOverlayController mNavbarOverlayController;
private final UiEventLogger mUiEventLogger;
private final NavBarHelper mNavBarHelper;
private final NotificationShadeDepthController mNotificationShadeDepthController;
+ private final UserContextProvider mUserContextProvider;
+ private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
private NavigationBarFrame mFrame;
private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
@@ -504,7 +512,6 @@
NotificationRemoteInputManager notificationRemoteInputManager,
NotificationShadeDepthController notificationShadeDepthController,
@Main Handler mainHandler,
- NavigationBarOverlayController navbarOverlayController,
UiEventLogger uiEventLogger,
NavBarHelper navBarHelper,
LightBarController mainLightBarController,
@@ -516,7 +523,9 @@
DeadZone deadZone,
DeviceConfigProxy deviceConfigProxy,
NavigationBarTransitions navigationBarTransitions,
- Optional<BackAnimation> backAnimation) {
+ EdgeBackGestureHandler edgeBackGestureHandler,
+ Optional<BackAnimation> backAnimation,
+ UserContextProvider userContextProvider) {
super(navigationBarView);
mFrame = navigationBarFrame;
mContext = context;
@@ -541,9 +550,9 @@
mDeadZone = deadZone;
mDeviceConfigProxy = deviceConfigProxy;
mNavigationBarTransitions = navigationBarTransitions;
+ mEdgeBackGestureHandler = edgeBackGestureHandler;
mBackAnimation = backAnimation;
mHandler = mainHandler;
- mNavbarOverlayController = navbarOverlayController;
mUiEventLogger = uiEventLogger;
mNavBarHelper = navBarHelper;
mNotificationShadeDepthController = notificationShadeDepthController;
@@ -553,7 +562,31 @@
mAutoHideControllerFactory = autoHideControllerFactory;
mTelecomManagerOptional = telecomManagerOptional;
mInputMethodManager = inputMethodManager;
+ mUserContextProvider = userContextProvider;
+ mOnComputeInternalInsetsListener = info -> {
+ // When the nav bar is in 2-button or 3-button mode, or when IME is visible in fully
+ // gestural mode, the entire nav bar should be touchable.
+ if (!mEdgeBackGestureHandler.isHandlingGestures()) {
+ // We're in 2/3 button mode OR back button force-shown in SUW
+ if (!mImeVisible) {
+ // IME not showing, take all touches
+ info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+ }
+ if (!mView.isImeRenderingNavButtons()) {
+ // IME showing but not drawing any buttons, take all touches
+ info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+ }
+ }
+
+ // When in gestural and the IME is showing, don't use the nearest region since it will
+ // take gesture space away from the IME
+ info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ info.touchableRegion.set(getButtonLocations(false /* includeFloatingButtons */,
+ false /* inScreen */, false /* useNearestRegion */));
+ };
+
+ mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler);
mNavBarMode = mNavigationModeController.addListener(mModeChangedListener);
}
@@ -568,6 +601,7 @@
mView.setBarTransitions(mNavigationBarTransitions);
mView.setTouchHandler(mTouchHandler);
mView.setNavBarMode(mNavBarMode);
+ mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
mView.updateRotationButton();
mView.setVisibility(
@@ -645,11 +679,14 @@
mView.setNavBarMode(mNavBarMode);
mView.setUpdateActiveTouchRegionsCallback(
() -> mOverviewProxyService.onActiveNavBarRegionChanges(
- mView.getButtonLocations(
+ getButtonLocations(
true /* includeFloatingButtons */,
true /* inScreen */,
true /* useNearestRegion */)));
+ mView.getViewTreeObserver().addOnComputeInternalInsetsListener(
+ mOnComputeInternalInsetsListener);
+
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mPipOptional.ifPresent(mView::addPipExclusionBoundsChangeListener);
@@ -720,6 +757,8 @@
mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
mOrientationHandleGlobalLayoutListener);
}
+ mView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
+ mOnComputeInternalInsetsListener);
mHandler.removeCallbacks(mAutoDim);
mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
mHandler.removeCallbacks(mEnableLayoutTransitions);
@@ -967,9 +1006,6 @@
@Override
public void onRecentsAnimationStateChanged(boolean running) {
- if (running) {
- mNavbarOverlayController.setButtonState(/* visible */false, /* force */true);
- }
mView.getRotationButtonController().setRecentsAnimationRunning(running);
}
@@ -1046,8 +1082,8 @@
}
private void handleTransientChanged() {
- mView.onTransientStateChanged(mTransientShown,
- mTransientShownFromGestureOnSystemBar);
+ mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTransientShown);
+
final int transitionMode = transitionMode(mTransientShown, mAppearance);
if (updateTransitionMode(transitionMode) && mLightBarController != null) {
mLightBarController.onNavigationBarModeChanged(transitionMode);
@@ -1518,35 +1554,36 @@
int insetsHeight = -1;
int gravity = Gravity.BOTTOM;
boolean navBarCanMove = true;
+ final Context userContext = mUserContextProvider.createCurrentUserContext(mContext);
if (mWindowManager != null && mWindowManager.getCurrentWindowMetrics() != null) {
Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
navBarCanMove = displaySize.width() != displaySize.height()
- && mContext.getResources().getBoolean(
+ && userContext.getResources().getBoolean(
com.android.internal.R.bool.config_navBarCanMove);
}
if (!navBarCanMove) {
- height = mContext.getResources().getDimensionPixelSize(
+ height = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_frame_height);
- insetsHeight = mContext.getResources().getDimensionPixelSize(
+ insetsHeight = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
} else {
switch (rotation) {
case ROTATION_UNDEFINED:
case Surface.ROTATION_0:
case Surface.ROTATION_180:
- height = mContext.getResources().getDimensionPixelSize(
+ height = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_frame_height);
- insetsHeight = mContext.getResources().getDimensionPixelSize(
+ insetsHeight = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
break;
case Surface.ROTATION_90:
gravity = Gravity.RIGHT;
- width = mContext.getResources().getDimensionPixelSize(
+ width = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width);
break;
case Surface.ROTATION_270:
gravity = Gravity.LEFT;
- width = mContext.getResources().getDimensionPixelSize(
+ width = userContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width);
break;
}
@@ -1571,12 +1608,12 @@
lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] = null;
}
lp.token = new Binder();
- lp.accessibilityTitle = mContext.getString(R.string.nav_bar);
+ lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC
| WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
lp.windowAnimations = 0;
- lp.setTitle("NavigationBar" + mContext.getDisplayId());
+ lp.setTitle("NavigationBar" + userContext.getDisplayId());
lp.setFitInsetsTypes(0 /* types */);
lp.setTrustedOverlay();
return lp;
@@ -1640,6 +1677,79 @@
mNavigationIconHints = hints;
}
+ /**
+ * @param includeFloatingButtons Whether to include the floating rotation and overlay button in
+ * the region for all the buttons
+ * @param inScreenSpace Whether to return values in screen space or window space
+ * @param useNearestRegion Whether to use the nearest region instead of the actual button bounds
+ * @return
+ */
+ Region getButtonLocations(boolean includeFloatingButtons, boolean inScreenSpace,
+ boolean useNearestRegion) {
+ if (useNearestRegion && !inScreenSpace) {
+ // We currently don't support getting the nearest region in anything but screen space
+ useNearestRegion = false;
+ }
+ Region region = new Region();
+ Map<View, Rect> touchRegionCache = mView.getButtonTouchRegionCache();
+ updateButtonLocation(
+ region, touchRegionCache, mView.getBackButton(), inScreenSpace, useNearestRegion);
+ updateButtonLocation(
+ region, touchRegionCache, mView.getHomeButton(), inScreenSpace, useNearestRegion);
+ updateButtonLocation(region, touchRegionCache, mView.getRecentsButton(), inScreenSpace,
+ useNearestRegion);
+ updateButtonLocation(region, touchRegionCache, mView.getImeSwitchButton(), inScreenSpace,
+ useNearestRegion);
+ updateButtonLocation(
+ region, touchRegionCache, mView.getAccessibilityButton(), inScreenSpace,
+ useNearestRegion);
+ if (includeFloatingButtons && mView.getFloatingRotationButton().isVisible()) {
+ // Note: this button is floating so the nearest region doesn't apply
+ updateButtonLocation(
+ region, mView.getFloatingRotationButton().getCurrentView(), inScreenSpace);
+ } else {
+ updateButtonLocation(region, touchRegionCache, mView.getRotateSuggestionButton(),
+ inScreenSpace, useNearestRegion);
+ }
+ return region;
+ }
+
+ private void updateButtonLocation(
+ Region region,
+ Map<View, Rect> touchRegionCache,
+ ButtonDispatcher button,
+ boolean inScreenSpace,
+ boolean useNearestRegion) {
+ if (button == null) {
+ return;
+ }
+ View view = button.getCurrentView();
+ if (view == null || !button.isVisible()) {
+ return;
+ }
+ // If the button is tappable from perspective of NearestTouchFrame, then we'll
+ // include the regions where the tap is valid instead of just the button layout location
+ if (useNearestRegion && touchRegionCache.containsKey(view)) {
+ region.op(touchRegionCache.get(view), Region.Op.UNION);
+ return;
+ }
+ updateButtonLocation(region, view, inScreenSpace);
+ }
+
+ private void updateButtonLocation(Region region, View view, boolean inScreenSpace) {
+ Rect bounds = new Rect();
+ if (inScreenSpace) {
+ view.getBoundsOnScreen(bounds);
+ } else {
+ int[] location = new int[2];
+ view.getLocationInWindow(location);
+ bounds.set(location[0], location[1],
+ location[0] + view.getWidth(),
+ location[1] + view.getHeight());
+ }
+ region.op(bounds, Region.Op.UNION);
+ }
+
private final ModeChangedListener mModeChangedListener = new ModeChangedListener() {
@Override
public void onNavigationModeChanged(int mode) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index 93bf136..f6bfd6c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -24,6 +24,7 @@
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import dagger.Module;
import dagger.Provides;
@@ -55,6 +56,14 @@
return barView.findViewById(R.id.navigation_bar_view);
}
+ /** */
+ @Provides
+ @NavigationBarScope
+ static EdgeBackGestureHandler provideEdgeBackGestureHandler(
+ EdgeBackGestureHandler.Factory factory, @DisplayId Context context) {
+ return factory.create(context);
+ }
+
/** A WindowManager specific to the display's context. */
@Provides
@NavigationBarScope
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java
deleted file mode 100644
index 9f2fb50..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarOverlayController.java
+++ /dev/null
@@ -1,87 +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.systemui.navigationbar;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.view.View;
-
-import com.android.systemui.dagger.SysUISingleton;
-
-import java.util.function.Consumer;
-
-import javax.inject.Inject;
-
-/** Contains logic that deals with showing buttons with navigation bar. */
-@SysUISingleton
-public class NavigationBarOverlayController {
-
- protected final Context mContext;
-
- @Inject
- public NavigationBarOverlayController(Context context) {
- mContext = context;
- }
-
- public Context getContext() {
- return mContext;
- }
-
- public boolean isNavigationBarOverlayEnabled() {
- return false;
- }
-
- /**
- * Initialize the controller with visibility change callback.
- */
- public void init(Consumer<Boolean> visibilityChangeCallback,
- Consumer<Rect> excludeBackRegionCallback) {}
-
- /**
- * Set whether the view can be shown.
- */
- public void setCanShow(boolean canShow) {}
-
- /**
- * Set the buttons visibility.
- */
- public void setButtonState(boolean visible, boolean force) {}
-
- /**
- * Register necessary listeners, called when NavigationBarView is attached to window.
- */
- public void registerListeners() {}
-
- /**
- * Unregister listeners, called when navigationBarView is detached from window.
- */
- public void unregisterListeners() {}
-
- /**
- * Return the current view.
- */
- public View getCurrentView() {
- return null;
- }
-
- /**
- * Return the visibility of the view.
- */
- public boolean isVisible() {
- return false;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index f3a3f10..a13c199 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -41,8 +41,6 @@
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.Region.Op;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
@@ -53,8 +51,6 @@
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver.InternalInsetsInfo;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.WindowInsets;
import android.view.WindowInsetsController.Behavior;
import android.view.WindowManager;
@@ -93,7 +89,6 @@
import com.android.wm.shell.pip.Pip;
import java.io.PrintWriter;
-import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -123,11 +118,6 @@
private int mNavBarMode;
private boolean mImeDrawsImeNavBar;
- private final Region mTmpRegion = new Region();
- private final int[] mTmpPosition = new int[2];
- private Rect mTmpBounds = new Rect();
- private Map<View, Rect> mButtonFullTouchableRegions = new HashMap<>();
-
private KeyButtonDrawable mBackIcon;
private KeyButtonDrawable mHomeDefaultIcon;
private KeyButtonDrawable mRecentIcon;
@@ -138,7 +128,6 @@
private EdgeBackGestureHandler mEdgeBackGestureHandler;
private final DeadZone mDeadZone;
- private boolean mDeadZoneConsuming = false;
private NavigationBarTransitions mBarTransitions;
@Nullable
private AutoHideController mAutoHideController;
@@ -152,7 +141,6 @@
private boolean mUseCarModeUi = false;
private boolean mInCarMode = false;
private boolean mDockedStackExists;
- private boolean mImeVisible;
private boolean mScreenOn = true;
private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
@@ -166,7 +154,6 @@
private RotationContextButton mRotationContextButton;
private FloatingRotationButton mFloatingRotationButton;
private RotationButtonController mRotationButtonController;
- private NavigationBarOverlayController mNavBarOverlayController;
/**
* Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -273,31 +260,6 @@
}
};
- private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener = info -> {
- // When the nav bar is in 2-button or 3-button mode, or when the back button is force-shown
- // while in gesture nav in SUW, the entire nav bar should be touchable.
- if (!mEdgeBackGestureHandler.isHandlingGestures()) {
- // We're in 2/3 button mode OR back button force-shown in SUW
- if (!mImeVisible) {
- // IME not showing, take all touches
- info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
- return;
- }
-
- if (!isImeRenderingNavButtons()) {
- // IME showing but not drawing any buttons, take all touches
- info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
- return;
- }
- }
-
- // When in gestural and the IME is showing, don't use the nearest region since it will take
- // gesture space away from the IME
- info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- info.touchableRegion.set(getButtonLocations(false /* includeFloatingButtons */,
- false /* inScreen */, false /* useNearestRegion */));
- };
-
private final RotationButtonUpdatesCallback mRotationButtonListener =
new RotationButtonUpdatesCallback() {
@Override
@@ -316,13 +278,6 @@
}
};
- private final Consumer<Boolean> mNavbarOverlayVisibilityChangeCallback = (visible) -> {
- if (visible && mAutoHideController != null) {
- mAutoHideController.touchAutoHide();
- }
- notifyActiveTouchRegions();
- };
-
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -381,9 +336,6 @@
mNavColorSampleMargin = getResources()
.getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
- mEdgeBackGestureHandler = Dependency.get(EdgeBackGestureHandler.Factory.class)
- .create(mContext);
- mEdgeBackGestureHandler.setStateChangeCallback(this::updateStates);
Executor backgroundExecutor = Dependency.get(Dependency.BACKGROUND_EXECUTOR);
mRegionSamplingHelper = new RegionSamplingHelper(this,
new RegionSamplingHelper.SamplingCallback() {
@@ -408,12 +360,10 @@
return isGesturalModeOnDefaultDisplay(getContext(), mNavBarMode);
}
}, backgroundExecutor);
+ }
- mNavBarOverlayController = Dependency.get(NavigationBarOverlayController.class);
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.init(mNavbarOverlayVisibilityChangeCallback,
- mEdgeBackGestureHandler::updateNavigationBarOverlayExcludeRegion);
- }
+ public void setEdgeBackGestureHandler(EdgeBackGestureHandler edgeBackGestureHandler) {
+ mEdgeBackGestureHandler = edgeBackGestureHandler;
}
void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
@@ -466,17 +416,6 @@
void onTransientStateChanged(boolean isTransient, boolean isGestureOnSystemBar) {
mEdgeBackGestureHandler.onNavBarTransientStateChanged(isTransient);
-
- // The visibility of the navigation bar buttons is dependent on the transient state of
- // the navigation bar.
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- // Always allow the overlay if in non-gestural nav mode, otherwise, only allow showing
- // the overlay if the user is swiping directly over a system bar
- boolean allowNavBarOverlay = !QuickStepContract.isGesturalMode(mNavBarMode)
- || isGestureOnSystemBar;
- isTransient = isTransient && allowNavBarOverlay;
- mNavBarOverlayController.setButtonState(isTransient, /* force */ false);
- }
}
void onBarTransition(int newMode) {
@@ -699,11 +638,7 @@
if (!visible) {
mTransitionListener.onBackAltCleared();
}
- mImeVisible = visible;
- mRotationButtonController.getRotationButton().setCanShowRotationButton(!mImeVisible);
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.setCanShow(!mImeVisible);
- }
+ mRotationButtonController.getRotationButton().setCanShowRotationButton(!visible);
}
void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
@@ -795,7 +730,7 @@
/**
* Returns whether the IME is currently visible and drawing the nav buttons.
*/
- private boolean isImeRenderingNavButtons() {
+ boolean isImeRenderingNavButtons() {
return mImeDrawsImeNavBar
&& mImeCanRenderGesturalNavButtons
&& (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0;
@@ -1024,80 +959,14 @@
notifyActiveTouchRegions();
}
- private void updateButtonTouchRegionCache() {
+ Map<View, Rect> getButtonTouchRegionCache() {
FrameLayout navBarLayout = mIsVertical
? mNavigationInflaterView.mVertical
: mNavigationInflaterView.mHorizontal;
- mButtonFullTouchableRegions = ((NearestTouchFrame) navBarLayout
+ return ((NearestTouchFrame) navBarLayout
.findViewById(R.id.nav_buttons)).getFullTouchableChildRegions();
}
- /**
- * @param includeFloatingButtons Whether to include the floating rotation and overlay button in
- * the region for all the buttons
- * @param inScreenSpace Whether to return values in screen space or window space
- * @param useNearestRegion Whether to use the nearest region instead of the actual button bounds
- * @return
- */
- Region getButtonLocations(boolean includeFloatingButtons, boolean inScreenSpace,
- boolean useNearestRegion) {
- // TODO: move this method to NavigationBar.
- // TODO: don't use member variables for temp storage like mTmpRegion.
- if (useNearestRegion && !inScreenSpace) {
- // We currently don't support getting the nearest region in anything but screen space
- useNearestRegion = false;
- }
- mTmpRegion.setEmpty();
- updateButtonTouchRegionCache();
- updateButtonLocation(getBackButton(), inScreenSpace, useNearestRegion);
- updateButtonLocation(getHomeButton(), inScreenSpace, useNearestRegion);
- updateButtonLocation(getRecentsButton(), inScreenSpace, useNearestRegion);
- updateButtonLocation(getImeSwitchButton(), inScreenSpace, useNearestRegion);
- updateButtonLocation(getAccessibilityButton(), inScreenSpace, useNearestRegion);
- if (includeFloatingButtons && mFloatingRotationButton.isVisible()) {
- // Note: this button is floating so the nearest region doesn't apply
- updateButtonLocation(mFloatingRotationButton.getCurrentView(), inScreenSpace);
- } else {
- updateButtonLocation(getRotateSuggestionButton(), inScreenSpace, useNearestRegion);
- }
- if (includeFloatingButtons && mNavBarOverlayController.isNavigationBarOverlayEnabled()
- && mNavBarOverlayController.isVisible()) {
- // Note: this button is floating so the nearest region doesn't apply
- updateButtonLocation(mNavBarOverlayController.getCurrentView(), inScreenSpace);
- }
- return mTmpRegion;
- }
-
- private void updateButtonLocation(ButtonDispatcher button, boolean inScreenSpace,
- boolean useNearestRegion) {
- if (button == null) {
- return;
- }
- View view = button.getCurrentView();
- if (view == null || !button.isVisible()) {
- return;
- }
- // If the button is tappable from perspective of NearestTouchFrame, then we'll
- // include the regions where the tap is valid instead of just the button layout location
- if (useNearestRegion && mButtonFullTouchableRegions.containsKey(view)) {
- mTmpRegion.op(mButtonFullTouchableRegions.get(view), Op.UNION);
- return;
- }
- updateButtonLocation(view, inScreenSpace);
- }
-
- private void updateButtonLocation(View view, boolean inScreenSpace) {
- if (inScreenSpace) {
- view.getBoundsOnScreen(mTmpBounds);
- } else {
- view.getLocationInWindow(mTmpPosition);
- mTmpBounds.set(mTmpPosition[0], mTmpPosition[1],
- mTmpPosition[0] + view.getWidth(),
- mTmpPosition[1] + view.getHeight());
- }
- mTmpRegion.op(mTmpBounds, Op.UNION);
- }
-
private void updateOrientationViews() {
mHorizontal = findViewById(R.id.horizontal);
mVertical = findViewById(R.id.vertical);
@@ -1297,11 +1166,7 @@
if (mRotationButtonController != null) {
mRotationButtonController.registerListeners();
}
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.registerListeners();
- }
- getViewTreeObserver().addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
updateNavButtonIcons();
}
@@ -1316,13 +1181,7 @@
mRotationButtonController.unregisterListeners();
}
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.unregisterListeners();
- }
-
mEdgeBackGestureHandler.onNavBarDetached();
- getViewTreeObserver().removeOnComputeInternalInsetsListener(
- mOnComputeInternalInsetsListener);
}
public void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 363baaa..8ee16a9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -87,7 +87,6 @@
private static final String TAG = TaskbarDelegate.class.getSimpleName();
private final EdgeBackGestureHandler mEdgeBackGestureHandler;
- private final NavigationBarOverlayController mNavBarOverlayController;
private final LightBarTransitionsController.Factory mLightBarTransitionsControllerFactory;
private boolean mInitialized;
private CommandQueue mCommandQueue;
@@ -158,16 +157,11 @@
public TaskbarDelegate(
Context context,
EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory,
- NavigationBarOverlayController navigationBarOverlayController,
LightBarTransitionsController.Factory lightBarTransitionsControllerFactory
) {
mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context);
- mNavBarOverlayController = navigationBarOverlayController;
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.init(mNavbarOverlayVisibilityChangeCallback,
- mEdgeBackGestureHandler::updateNavigationBarOverlayExcludeRegion);
- }
+
mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds;
@@ -227,9 +221,6 @@
mNavigationModeController.addListener(this));
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.init();
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.registerListeners();
- }
mEdgeBackGestureHandler.onNavBarAttached();
// Initialize component callback
Display display = mDisplayManager.getDisplay(displayId);
@@ -254,9 +245,6 @@
mNavigationModeController.removeListener(this);
mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.destroy();
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.unregisterListeners();
- }
mEdgeBackGestureHandler.onNavBarDetached();
mScreenPinningNotify = null;
if (mWindowContext != null) {
@@ -425,19 +413,10 @@
private void onTransientStateChanged() {
mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTaskbarTransientShowing);
-
- // The visibility of the navigation bar buttons is dependent on the transient state of
- // the navigation bar.
- if (mNavBarOverlayController.isNavigationBarOverlayEnabled()) {
- mNavBarOverlayController.setButtonState(mTaskbarTransientShowing, /* force */ false);
- }
}
@Override
public void onRecentsAnimationStateChanged(boolean running) {
- if (running) {
- mNavBarOverlayController.setButtonState(/* visible */false, /* force */true);
- }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/power/dagger/PowerModule.java b/packages/SystemUI/src/com/android/systemui/power/dagger/PowerModule.java
index 8b8941a..3709a86 100644
--- a/packages/SystemUI/src/com/android/systemui/power/dagger/PowerModule.java
+++ b/packages/SystemUI/src/com/android/systemui/power/dagger/PowerModule.java
@@ -16,6 +16,8 @@
package com.android.systemui.power.dagger;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.power.PowerNotificationWarnings;
import com.android.systemui.power.PowerUI;
@@ -28,5 +30,9 @@
public interface PowerModule {
/** */
@Binds
+ EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
+
+ /** */
+ @Binds
PowerUI.WarningsUI provideWarningsUi(PowerNotificationWarnings controllerImpl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 3eb4b10..3e8cdf3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -420,7 +420,7 @@
PowerExemptionManager.REASON_SYSTEM_UID,
PowerExemptionManager.REASON_DEVICE_DEMO_MODE -> UIControl.HIDE_ENTRY
- PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE,
+ PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED,
PowerExemptionManager.REASON_DEVICE_OWNER,
PowerExemptionManager.REASON_DISALLOW_APPS_CONTROL,
PowerExemptionManager.REASON_DPO_PROTECTED_APP,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 7d3df6e..5d2060d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -47,9 +47,10 @@
private QSCustomizer mQSCustomizer;
private NonInterceptingScrollView mQSPanelContainer;
- private int mSideMargins;
+ private int mHorizontalMargins;
+ private int mTilesPageMargin;
private boolean mQsDisabled;
- private int mContentPadding = -1;
+ private int mContentHorizontalPadding = -1;
private boolean mClippingEnabled;
public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -145,12 +146,17 @@
mQSPanelContainer.getPaddingEnd(),
bottomPadding);
- int sideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
- int padding = getResources().getDimensionPixelSize(
- R.dimen.notification_shade_content_margin_horizontal);
- boolean marginsChanged = padding != mContentPadding || sideMargins != mSideMargins;
- mContentPadding = padding;
- mSideMargins = sideMargins;
+ int horizontalMargins = getResources().getDimensionPixelSize(R.dimen.qs_horizontal_margin);
+ int horizontalPadding = getResources().getDimensionPixelSize(
+ R.dimen.qs_content_horizontal_padding);
+ int tilesPageMargin = getResources().getDimensionPixelSize(
+ R.dimen.qs_tiles_page_horizontal_margin);
+ boolean marginsChanged = horizontalPadding != mContentHorizontalPadding
+ || horizontalMargins != mHorizontalMargins
+ || tilesPageMargin != mTilesPageMargin;
+ mContentHorizontalPadding = horizontalPadding;
+ mHorizontalMargins = horizontalMargins;
+ mTilesPageMargin = tilesPageMargin;
if (marginsChanged) {
updatePaddingsAndMargins(qsPanelController, quickStatusBarHeaderController);
}
@@ -198,22 +204,22 @@
// Only padding for FooterActionsView, no margin. That way, the background goes
// all the way to the edge.
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- lp.rightMargin = mSideMargins;
- lp.leftMargin = mSideMargins;
+ lp.rightMargin = mHorizontalMargins;
+ lp.leftMargin = mHorizontalMargins;
}
if (view == mQSPanelContainer) {
// QS panel lays out some of its content full width
- qsPanelController.setContentMargins(mContentPadding, mContentPadding);
- // Set it as double the side margin (to simulate end margin of current page +
- // start margin of next page).
- qsPanelController.setPageMargin(mSideMargins);
+ qsPanelController.setContentMargins(mContentHorizontalPadding,
+ mContentHorizontalPadding);
+ qsPanelController.setPageMargin(mTilesPageMargin);
} else if (view == mHeader) {
- quickStatusBarHeaderController.setContentMargins(mContentPadding, mContentPadding);
+ quickStatusBarHeaderController.setContentMargins(mContentHorizontalPadding,
+ mContentHorizontalPadding);
} else {
view.setPaddingRelative(
- mContentPadding,
+ mContentHorizontalPadding,
view.getPaddingTop(),
- mContentPadding,
+ mContentHorizontalPadding,
view.getPaddingBottom());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 772e9fa..248c78e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -147,16 +147,9 @@
if (mController.getWalletClient().isWalletServiceAvailable()
&& mController.getWalletClient().isWalletFeatureAvailable()) {
if (mSelectedCard != null) {
- if (isDeviceLocked) {
- state.state = Tile.STATE_INACTIVE;
- state.secondaryLabel =
- mContext.getString(R.string.wallet_secondary_label_device_locked);
- state.sideViewCustomDrawable = null;
- } else {
- state.state = Tile.STATE_ACTIVE;
- state.secondaryLabel = mSelectedCard.getContentDescription();
- state.sideViewCustomDrawable = mCardViewDrawable;
- }
+ state.state = isDeviceLocked ? Tile.STATE_INACTIVE : Tile.STATE_ACTIVE;
+ state.secondaryLabel = mSelectedCard.getContentDescription();
+ state.sideViewCustomDrawable = mCardViewDrawable;
} else {
state.state = Tile.STATE_INACTIVE;
state.secondaryLabel =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
index f4dd415..d99c1d1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
@@ -92,15 +92,15 @@
@Override
protected void handleClick(@Nullable View view) {
- if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
- mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
- mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(),
- !mSensorPrivacyController.isSensorBlocked(getSensorId()));
- });
+ boolean blocked = mSensorPrivacyController.isSensorBlocked(getSensorId());
+ if (mSensorPrivacyController.requiresAuthentication()
+ && mKeyguard.isMethodSecure()
+ && mKeyguard.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(() ->
+ mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(), !blocked));
return;
}
- mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(),
- !mSensorPrivacyController.isSensorBlocked(getSensorId()));
+ mSensorPrivacyController.setSensorBlocked(QS_TILE, getSensorId(), !blocked);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 6af6e36..ccfcaa6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -149,7 +149,6 @@
private ImageView mActionsContainerBackground;
private HorizontalScrollView mActionsContainer;
private LinearLayout mActionsView;
- private ImageView mBackgroundProtection;
private FrameLayout mDismissButton;
private OverlayActionChip mShareChip;
private OverlayActionChip mEditChip;
@@ -345,8 +344,6 @@
R.id.actions_container_background));
mActionsContainer = requireNonNull(findViewById(R.id.actions_container));
mActionsView = requireNonNull(findViewById(R.id.screenshot_actions));
- mBackgroundProtection = requireNonNull(
- findViewById(R.id.screenshot_actions_background));
mDismissButton = requireNonNull(findViewById(R.id.screenshot_dismiss_button));
mScrollablePreview = requireNonNull(findViewById(R.id.screenshot_scrollable_preview));
mScreenshotFlash = requireNonNull(findViewById(R.id.screenshot_flash));
@@ -394,14 +391,6 @@
}
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
mPackageName);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- mBackgroundProtection.animate()
- .alpha(0).setDuration(animation.getDuration()).start();
- }
- });
}
@Override
@@ -704,7 +693,6 @@
animator.addUpdateListener(animation -> {
float t = animation.getAnimatedFraction();
- mBackgroundProtection.setAlpha(t);
float containerAlpha = t < alphaFraction ? t / alphaFraction : 1;
mActionsContainer.setAlpha(containerAlpha);
mActionsContainerBackground.setAlpha(containerAlpha);
@@ -910,7 +898,6 @@
}
mDismissButton.setVisibility(View.GONE);
mActionsContainer.setVisibility(View.GONE);
- mBackgroundProtection.setVisibility(View.GONE);
// set these invisible, but not gone, so that the views are laid out correctly
mActionsContainerBackground.setVisibility(View.INVISIBLE);
mScreenshotPreviewBorder.setVisibility(View.INVISIBLE);
@@ -932,7 +919,6 @@
mDismissButton.setVisibility(View.VISIBLE);
}
mActionsContainer.setVisibility(View.VISIBLE);
- mBackgroundProtection.setVisibility(View.VISIBLE);
mActionsContainerBackground.setVisibility(View.VISIBLE);
mScreenshotPreviewBorder.setVisibility(View.VISIBLE);
mScreenshotPreview.setVisibility(View.VISIBLE);
@@ -969,7 +955,6 @@
mPendingSharedTransition = false;
mActionsContainerBackground.setVisibility(View.GONE);
mActionsContainer.setVisibility(View.GONE);
- mBackgroundProtection.setAlpha(0f);
mDismissButton.setVisibility(View.GONE);
mScrollingScrim.setVisibility(View.GONE);
mScrollablePreview.setVisibility(View.GONE);
@@ -1016,7 +1001,6 @@
mDismissButton.setAlpha(alpha);
mActionsContainerBackground.setAlpha(alpha);
mActionsContainer.setAlpha(alpha);
- mBackgroundProtection.setAlpha(alpha);
mScreenshotPreviewBorder.setAlpha(alpha);
});
alphaAnim.setDuration(600);
diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
index dae375a..2d1d8b7 100644
--- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
@@ -134,7 +134,9 @@
override fun onClick(dialog: DialogInterface?, which: Int) {
when (which) {
BUTTON_POSITIVE -> {
- if (keyguardStateController.isMethodSecure && keyguardStateController.isShowing) {
+ if (sensorPrivacyController.requiresAuthentication() &&
+ keyguardStateController.isMethodSecure &&
+ keyguardStateController.isShowing) {
keyguardDismissUtil.executeWhenUnlocked({
bgHandler.postDelayed({
disableSensorPrivacy()
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt b/packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
index 27af152..dae8512 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
@@ -23,4 +23,10 @@
*/
interface UserContextProvider {
val userContext: Context
+
+ /**
+ * Creates the {@code context} with the current user.
+ * @see Context#createContextAsUser(UserHandle, int)
+ */
+ fun createCurrentUserContext(context: Context): Context
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 3a6248b..80d5f16 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -127,6 +127,12 @@
}
}
+ override fun createCurrentUserContext(context: Context): Context {
+ synchronized(mutex) {
+ return context.createContextAsUser(userHandle, 0)
+ }
+ }
+
private fun setUserIdInternal(user: Int): Pair<Context, List<UserInfo>> {
val profiles = userManager.getProfiles(user)
val handle = UserHandle(user)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
index ebd610b..0c9e1ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java
@@ -180,13 +180,6 @@
default void setRequestTopUi(boolean requestTopUi, String componentTag) {}
/**
- * Under low light conditions, we might want to increase the display brightness on devices that
- * don't have an IR camera.
- * @param brightness float from 0 to 1 or {@code LayoutParams.BRIGHTNESS_OVERRIDE_NONE}
- */
- default void setFaceAuthDisplayBrightness(float brightness) {}
-
- /**
* If {@link LightRevealScrim} obscures the UI.
* @param opaque if the scrim is opaque
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
index a390e9f..15ad312 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
@@ -20,11 +20,13 @@
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.render.NodeController
import com.android.systemui.statusbar.notification.dagger.PeopleHeader
+import com.android.systemui.statusbar.notification.icon.ConversationIconManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
@@ -39,12 +41,40 @@
@CoordinatorScope
class ConversationCoordinator @Inject constructor(
private val peopleNotificationIdentifier: PeopleNotificationIdentifier,
+ private val conversationIconManager: ConversationIconManager,
@PeopleHeader peopleHeaderController: NodeController
) : Coordinator {
+ private val promotedEntriesToSummaryOfSameChannel =
+ mutableMapOf<NotificationEntry, NotificationEntry>()
+
+ private val onBeforeRenderListListener = OnBeforeRenderListListener { _ ->
+ val unimportantSummaries = promotedEntriesToSummaryOfSameChannel
+ .mapNotNull { (promoted, summary) ->
+ val originalGroup = summary.parent
+ when {
+ originalGroup == null -> null
+ originalGroup == promoted.parent -> null
+ originalGroup.parent == null -> null
+ originalGroup.summary != summary -> null
+ originalGroup.children.any { it.channel == summary.channel } -> null
+ else -> summary.key
+ }
+ }
+ conversationIconManager.setUnimportantConversations(unimportantSummaries)
+ promotedEntriesToSummaryOfSameChannel.clear()
+ }
+
private val notificationPromoter = object : NotifPromoter(TAG) {
override fun shouldPromoteToTopLevel(entry: NotificationEntry): Boolean {
- return entry.channel?.isImportantConversation == true
+ val shouldPromote = entry.channel?.isImportantConversation == true
+ if (shouldPromote) {
+ val summary = entry.parent?.summary
+ if (summary != null && entry.channel == summary.channel) {
+ promotedEntriesToSummaryOfSameChannel[entry] = summary
+ }
+ }
+ return shouldPromote
}
}
@@ -67,6 +97,7 @@
override fun attach(pipeline: NotifPipeline) {
pipeline.addPromoter(notificationPromoter)
+ pipeline.addOnBeforeRenderListListener(onBeforeRenderListListener)
}
private fun isConversation(entry: ListEntry): Boolean =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index 386e2d3..f460644 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -18,7 +18,6 @@
import android.annotation.MainThread
import android.view.View
-import com.android.systemui.util.kotlin.transform
import com.android.systemui.util.traceSection
/**
@@ -41,7 +40,6 @@
) {
private val rootNode = ShadeNode(rootController)
private val nodes = mutableMapOf(rootController to rootNode)
- private val views = mutableMapOf<View, ShadeNode>()
/**
* Adds and removes views from the root (and its children) until their structure matches the
@@ -66,26 +64,25 @@
*
* For debugging purposes.
*/
- fun getViewLabel(view: View): String = views[view]?.label ?: view.toString()
+ fun getViewLabel(view: View): String =
+ nodes.values.firstOrNull { node -> node.view === view }?.label ?: view.toString()
- private fun detachChildren(
- parentNode: ShadeNode,
- specMap: Map<NodeController, NodeSpec>
- ) {
- val parentSpec = specMap[parentNode.controller]
-
- for (i in parentNode.getChildCount() - 1 downTo 0) {
- val childView = parentNode.getChildAt(i)
- views[childView]?.let { childNode ->
- val childSpec = specMap[childNode.controller]
-
- maybeDetachChild(parentNode, parentSpec, childNode, childSpec)
-
- if (childNode.controller.getChildCount() > 0) {
- detachChildren(childNode, specMap)
+ private fun detachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
+ val views = nodes.values.associateBy { it.view }
+ fun detachRecursively(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
+ val parentSpec = specMap[parentNode.controller]
+ for (i in parentNode.getChildCount() - 1 downTo 0) {
+ val childView = parentNode.getChildAt(i)
+ views[childView]?.let { childNode ->
+ val childSpec = specMap[childNode.controller]
+ maybeDetachChild(parentNode, parentSpec, childNode, childSpec)
+ if (childNode.controller.getChildCount() > 0) {
+ detachRecursively(childNode, specMap)
+ }
}
}
}
+ detachRecursively(parentNode, specMap)
}
private fun maybeDetachChild(
@@ -94,14 +91,13 @@
childNode: ShadeNode,
childSpec: NodeSpec?
) {
- val newParentNode = transform(childSpec?.parent) { getNode(it) }
+ val newParentNode = childSpec?.parent?.let { getNode(it) }
if (newParentNode != parentNode) {
val childCompletelyRemoved = newParentNode == null
if (childCompletelyRemoved) {
nodes.remove(childNode.controller)
- views.remove(childNode.controller.view)
}
logger.logDetachingChild(
@@ -115,10 +111,7 @@
}
}
- private fun attachChildren(
- parentNode: ShadeNode,
- specMap: Map<NodeController, NodeSpec>
- ) {
+ private fun attachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
val parentSpec = checkNotNull(specMap[parentNode.controller])
for ((index, childSpec) in parentSpec.children.withIndex()) {
@@ -160,7 +153,6 @@
if (node == null) {
node = ShadeNode(spec.controller)
nodes[node.controller] = node
- views[node.view] = node
}
return node
}
@@ -194,10 +186,9 @@
private class DuplicateNodeException(message: String) : RuntimeException(message)
-private class ShadeNode(
- val controller: NodeController
-) {
- val view = controller.view
+private class ShadeNode(val controller: NodeController) {
+ val view: View
+ get() = controller.view
var parent: ShadeNode? = null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 34c8044..d96590a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -70,6 +70,8 @@
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.icon.ConversationIconManager;
+import com.android.systemui.statusbar.notification.icon.IconManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
@@ -370,6 +372,10 @@
/** */
@Binds
+ ConversationIconManager bindConversationIconManager(IconManager iconManager);
+
+ /** */
+ @Binds
BindEventManager bindBindEventManagerImpl(BindEventManagerImpl bindEventManagerImpl);
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 5375ac3..d896541 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -27,6 +27,7 @@
import android.widget.ImageView
import com.android.internal.statusbar.StatusBarIcon
import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.InflationException
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -44,11 +45,14 @@
* TODO: Much of this code was copied whole-sale in order to get it out of NotificationEntry.
* Long-term, it should probably live somewhere in the content inflation pipeline.
*/
+@SysUISingleton
class IconManager @Inject constructor(
private val notifCollection: CommonNotifCollection,
private val launcherApps: LauncherApps,
private val iconBuilder: IconBuilder
-) {
+) : ConversationIconManager {
+ private var unimportantConversationKeys: Set<String> = emptySet()
+
fun attach() {
notifCollection.addCollectionListener(entryListener)
}
@@ -63,16 +67,8 @@
}
override fun onRankingApplied() {
- // When the sensitivity changes OR when the isImportantConversation status changes,
- // we need to update the icons
- for (entry in notifCollection.allNotifs) {
- val isImportant = isImportantConversation(entry)
- if (entry.icons.areIconsAvailable &&
- isImportant != entry.icons.isImportantConversation) {
- updateIconsSafe(entry)
- }
- entry.icons.isImportantConversation = isImportant
- }
+ // rankings affect whether a conversation is important, which can change the icons
+ recalculateForImportantConversationChange()
}
}
@@ -80,6 +76,18 @@
entry -> updateIconsSafe(entry)
}
+ private fun recalculateForImportantConversationChange() {
+ for (entry in notifCollection.allNotifs) {
+ val isImportant = isImportantConversation(entry)
+ if (entry.icons.areIconsAvailable &&
+ isImportant != entry.icons.isImportantConversation
+ ) {
+ updateIconsSafe(entry)
+ }
+ entry.icons.isImportantConversation = isImportant
+ }
+ }
+
/**
* Inflate icon views for each icon variant and assign appropriate icons to them. Stores the
* result in [NotificationEntry.getIcons].
@@ -306,8 +314,28 @@
}
private fun isImportantConversation(entry: NotificationEntry): Boolean {
- return entry.ranking.channel != null && entry.ranking.channel.isImportantConversation
+ return entry.ranking.channel != null &&
+ entry.ranking.channel.isImportantConversation &&
+ entry.key !in unimportantConversationKeys
+ }
+
+ override fun setUnimportantConversations(keys: Collection<String>) {
+ val newKeys = keys.toSet()
+ val changed = unimportantConversationKeys != newKeys
+ unimportantConversationKeys = newKeys
+ if (changed) {
+ recalculateForImportantConversationChange()
+ }
}
}
-private const val TAG = "IconManager"
\ No newline at end of file
+private const val TAG = "IconManager"
+
+interface ConversationIconManager {
+ /**
+ * Sets the complete current set of notification keys which should (for the purposes of icon
+ * presentation) be considered unimportant. This tells the icon manager to remove the avatar
+ * of a group from which the priority notification has been removed.
+ */
+ fun setUnimportantConversations(keys: Collection<String>)
+}
\ No newline at end of file
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 5646545..cff42f2 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
@@ -18,6 +18,8 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
@@ -72,7 +74,7 @@
private val lockscreenUserManager: NotificationLockscreenUserManager,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val highPriorityProvider: HighPriorityProvider,
- private val statusBarStateController: StatusBarStateController,
+ private val statusBarStateController: SysuiStatusBarStateController,
private val broadcastDispatcher: BroadcastDispatcher,
private val secureSettings: SecureSettings,
private val globalSettings: GlobalSettings
@@ -105,7 +107,8 @@
if (uri == showSilentNotifsUri) {
readShowSilentNotificationSetting()
}
- if (keyguardStateController.isShowing) {
+ if (statusBarStateController.getCurrentOrUpcomingState()
+ == StatusBarState.KEYGUARD) {
notifyStateChanged("Settings $uri changed")
}
}
@@ -131,13 +134,14 @@
// register (maybe) public mode changed callbacks:
statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
- override fun onStateChanged(state: Int) {
- notifyStateChanged("onStatusBarStateChanged")
+ override fun onUpcomingStateChanged(state: Int) {
+ notifyStateChanged("onStatusBarUpcomingStateChanged")
}
})
broadcastDispatcher.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
- if (keyguardStateController.isShowing) {
+ if (statusBarStateController.getCurrentOrUpcomingState()
+ == StatusBarState.KEYGUARD) {
// maybe public mode changed
notifyStateChanged(intent.action!!)
}
@@ -159,17 +163,28 @@
override fun shouldHideNotification(entry: NotificationEntry): Boolean = when {
// Keyguard state doesn't matter if the keyguard is not showing.
- !keyguardStateController.isShowing -> false
+ statusBarStateController.getCurrentOrUpcomingState() != StatusBarState.KEYGUARD -> 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
+ // if entry is silent, apply custom logic to see if should hide
+ shouldHideIfEntrySilent(entry) -> true
+ else -> false
+ }
+
+ private fun shouldHideIfEntrySilent(entry: ListEntry): Boolean = when {
+ // Show if high priority (not hidden)
+ highPriorityProvider.isHighPriority(entry) -> false
+ // Ambient notifications are hidden always from lock screen
+ entry.representativeEntry?.isAmbient == true -> true
+ // [Now notification is silent]
+ // Hide regardless of parent priority if user wants silent notifs hidden
+ hideSilentNotificationsOnLockscreen -> 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
+ entry.parent?.let(::shouldHideIfEntrySilent) == false -> false
+ // Show when silent notifications are allowed on lockscreen
+ else -> false
}
private fun userSettingsDisallowNotification(entry: NotificationEntry): Boolean {
@@ -193,11 +208,6 @@
}
}
- private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry): Boolean = when {
- hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry)
- else -> entry.representativeEntry?.ranking?.isAmbient == false
- }
-
private fun readShowSilentNotificationSetting() {
val showSilentNotifs =
secureSettings.getBoolForUser(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index 6b79680..f0b221d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -160,8 +160,7 @@
val channels = groupList
.flatMap { group ->
group.channels.asSequence().filterNot { channel ->
- channel.isImportanceLockedByOEM ||
- channel.importance == IMPORTANCE_NONE ||
+ channel.importance == IMPORTANCE_NONE ||
channel.isImportanceLockedByCriticalDeviceFunction
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 0ae3653..dff8c47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -376,44 +376,24 @@
* calls.
*/
private static Boolean isSystemNotification(Context context, StatusBarNotification sbn) {
- // TODO (b/194833441): clean up before launch
- if (Settings.Secure.getIntForUser(context.getContentResolver(),
- Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) == 1) {
- INotificationManager iNm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ INotificationManager iNm = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- boolean isSystem = false;
- try {
- isSystem = iNm.isPermissionFixed(sbn.getPackageName(), sbn.getUserId());
- } catch (RemoteException e) {
- Log.e(TAG, "cannot reach NMS");
- }
- RoleManager rm = context.getSystemService(RoleManager.class);
- List<String> fixedRoleHolders = new ArrayList<>();
- fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_DIALER));
- fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_EMERGENCY));
- if (fixedRoleHolders.contains(sbn.getPackageName())) {
- isSystem = true;
- }
-
- return isSystem;
- } else {
- PackageManager packageManager = CentralSurfaces.getPackageManagerForUser(
- context, sbn.getUser().getIdentifier());
- Boolean isSystemNotification = null;
-
- try {
- PackageInfo packageInfo = packageManager.getPackageInfo(
- sbn.getPackageName(), PackageManager.GET_SIGNATURES);
-
- isSystemNotification =
- com.android.settingslib.Utils.isSystemPackage(
- context.getResources(), packageManager, packageInfo);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, "cacheIsSystemNotification: Could not find package info");
- }
- return isSystemNotification;
+ boolean isSystem = false;
+ try {
+ isSystem = iNm.isPermissionFixed(sbn.getPackageName(), sbn.getUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "cannot reach NMS");
}
+ RoleManager rm = context.getSystemService(RoleManager.class);
+ List<String> fixedRoleHolders = new ArrayList<>();
+ fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_DIALER));
+ fixedRoleHolders.addAll(rm.getRoleHolders(RoleManager.ROLE_EMERGENCY));
+ if (fixedRoleHolders.contains(sbn.getPackageName())) {
+ isSystem = true;
+ }
+
+ return isSystem;
}
public NotificationContentView[] getLayouts() {
@@ -567,9 +547,7 @@
mEntry.mIsSystemNotification = isSystemNotification(mContext, mEntry.getSbn());
}
- // TODO (b/194833441): remove when we've migrated to permission
- boolean isNonblockable = mEntry.getChannel().isImportanceLockedByOEM()
- || mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction();
+ boolean isNonblockable = mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction();
if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) {
if (mEntry.mIsSystemNotification) {
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 36cd173..3ea5e5b 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
@@ -70,6 +70,7 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.policy.SystemBarUtils;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.keyguard.KeyguardSliceView;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
@@ -1313,7 +1314,10 @@
final float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
+ mAmbientState.getOverExpansion()
- getCurrentOverScrollAmount(false /* top */);
- final float fraction = mAmbientState.getExpansionFraction();
+ float fraction = mAmbientState.getExpansionFraction();
+ if (mAmbientState.isBouncerInTransit()) {
+ fraction = BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(fraction);
+ }
final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
mAmbientState.setStackY(stackY);
if (mOnStackYChanged != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index ef24d77..5c12671 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1022,6 +1022,23 @@
public void onUnlockedChanged() {
logStateToEventlog();
}
+
+ @Override
+ public void onKeyguardGoingAwayChanged() {
+ // The light reveal scrim should always be fully revealed by the time the keyguard
+ // is done going away. Double check that this is true.
+ if (!mKeyguardStateController.isKeyguardGoingAway()) {
+ if (mLightRevealScrim.getRevealAmount() != 1f) {
+ Log.e(TAG, "Keyguard is done going away, but someone left the light reveal "
+ + "scrim at reveal amount: " + mLightRevealScrim.getRevealAmount());
+ }
+
+ // If the auth ripple is still playing, let it finish.
+ if (!mAuthRippleController.isAnimatingLightRevealScrim()) {
+ mLightRevealScrim.setRevealAmount(1f);
+ }
+ }
+ }
});
startKeyguard();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 69beaf56..0b72138 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -220,7 +220,7 @@
DejankUtils.postAfterTraversal(mShowRunnable);
}
- mCallback.onBouncerVisiblityChanged(true /* shown */);
+ mKeyguardStateController.notifyBouncerShowing(true /* showing */);
dispatchStartingToShow();
} finally {
Trace.endSection();
@@ -334,7 +334,7 @@
}
mIsScrimmed = false;
mFalsingCollector.onBouncerHidden();
- mCallback.onBouncerVisiblityChanged(false /* shown */);
+ mKeyguardStateController.notifyBouncerShowing(false /* showing */);
cancelShowRunnable();
if (mKeyguardViewController != null) {
mKeyguardViewController.cancelDismissAction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 83970dc..629aa03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -220,7 +220,7 @@
}
}
- public float getMinStackScrollerPadding() {
+ public float getLockscreenMinStackScrollerPadding() {
if (mBypassEnabled) {
return mUnlockedStackScrollerPadding;
} else if (mIsSplitShade) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt
new file mode 100644
index 0000000..0623507
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NPVCDownEventState.kt
@@ -0,0 +1,143 @@
+/*
+ * 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
+
+import android.view.MotionEvent
+import com.android.internal.util.RingBuffer
+import com.android.systemui.dump.DumpsysTableLogger
+import com.android.systemui.dump.Row
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+/** Container for storing information about [MotionEvent.ACTION_DOWN] on
+ * [NotificationPanelViewController].
+ *
+ * This will be used in a dump to log the latest recorded down events.
+ *
+ * @see NotificationPanelViewController.initDownStates
+ */
+class NPVCDownEventState private constructor(
+ private var timeStamp: Long = 0,
+ private var x: Float = 0f,
+ private var y: Float = 0f,
+ private var qsTouchAboveFalsingThreshold: Boolean = false,
+ private var dozing: Boolean = false,
+ private var collapsed: Boolean = false,
+ private var canCollapseOnQQS: Boolean = false,
+ private var listenForHeadsUp: Boolean = false,
+ private var allowExpandForSmallExpansion: Boolean = false,
+ private var touchSlopExceededBeforeDown: Boolean = false,
+ private var lastEventSynthesized: Boolean = false
+) {
+
+ /**
+ * List of [String] to be used as a [Row] with [DumpsysTableLogger].
+ */
+ val asStringList: List<String> by lazy {
+ listOf(
+ DATE_FORMAT.format(timeStamp),
+ x.toString(),
+ y.toString(),
+ qsTouchAboveFalsingThreshold.toString(),
+ dozing.toString(),
+ collapsed.toString(),
+ canCollapseOnQQS.toString(),
+ listenForHeadsUp.toString(),
+ allowExpandForSmallExpansion.toString(),
+ touchSlopExceededBeforeDown.toString(),
+ lastEventSynthesized.toString()
+ )
+ }
+
+ /**
+ * [RingBuffer] to store [NPVCDownEventState]. After the buffer is full, it will recycle old
+ * events.
+ *
+ * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
+ * necessary.
+ */
+ class Buffer(
+ capacity: Int
+ ) : RingBuffer<NPVCDownEventState>(NPVCDownEventState::class.java, capacity) {
+ override fun append(t: NPVCDownEventState?) {
+ throw UnsupportedOperationException("Not supported, use insert instead")
+ }
+
+ override fun createNewItem(): NPVCDownEventState {
+ return NPVCDownEventState()
+ }
+
+ /**
+ * Insert a new element in the buffer.
+ */
+ fun insert(
+ timeStamp: Long,
+ x: Float,
+ y: Float,
+ qsTouchAboveFalsingThreshold: Boolean,
+ dozing: Boolean,
+ collapsed: Boolean,
+ canCollapseOnQQS: Boolean,
+ listenForHeadsUp: Boolean,
+ allowExpandForSmallExpansion: Boolean,
+ touchSlopExceededBeforeDown: Boolean,
+ lastEventSynthesized: Boolean
+ ) {
+ nextSlot.apply {
+ this.timeStamp = timeStamp
+ this.x = x
+ this.y = y
+ this.qsTouchAboveFalsingThreshold = qsTouchAboveFalsingThreshold
+ this.dozing = dozing
+ this.collapsed = collapsed
+ this.canCollapseOnQQS = canCollapseOnQQS
+ this.listenForHeadsUp = listenForHeadsUp
+ this.allowExpandForSmallExpansion = allowExpandForSmallExpansion
+ this.touchSlopExceededBeforeDown = touchSlopExceededBeforeDown
+ this.lastEventSynthesized = lastEventSynthesized
+ }
+ }
+
+ /**
+ * Returns the content of the buffer (sorted from latest to newest).
+ *
+ * @see NPVCDownEventState.asStringList
+ */
+ fun toList(): List<Row> {
+ return toArray().map { it.asStringList }
+ }
+ }
+
+ companion object {
+ /**
+ * Headers for dumping a table using [DumpsysTableLogger].
+ */
+ @JvmField
+ val TABLE_HEADERS = listOf(
+ "Timestamp",
+ "X",
+ "Y",
+ "QSTouchAboveFalsingThreshold",
+ "Dozing",
+ "Collapsed",
+ "CanCollapseOnQQS",
+ "ListenForHeadsUp",
+ "AllowExpandForSmallExpansion",
+ "TouchSlopExceededBeforeDown",
+ "LastEventSynthesized"
+ )
+ }
+}
+
+private val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
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 b5789fb..77b9efa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -24,6 +24,7 @@
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
+import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -36,6 +37,7 @@
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPEN;
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_OPENING;
+import static com.android.systemui.util.DumpUtilsKt.asIndenting;
import static java.lang.Float.isNaN;
@@ -65,13 +67,13 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.os.Trace;
import android.os.UserManager;
import android.os.VibrationEffect;
import android.provider.Settings;
import android.transition.ChangeBounds;
import android.transition.TransitionManager;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -121,6 +123,7 @@
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
+import com.android.systemui.dump.DumpsysTableLogger;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -193,6 +196,7 @@
import com.android.systemui.util.ListenerSet;
import com.android.systemui.util.Utils;
import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -212,7 +216,7 @@
@CentralSurfacesComponent.CentralSurfacesScope
public class NotificationPanelViewController extends PanelViewController {
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
* The parallax amount of the quick settings translation when dragging down the panel
@@ -279,6 +283,8 @@
*/
private static final int MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER = 300;
+ private static final int MAX_DOWN_EVENT_BUFFER_SIZE = 50;
+
private static final String COUNTER_PANEL_OPEN = "panel_open";
private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
@@ -320,6 +326,11 @@
private boolean mShouldUseSplitNotificationShade;
// The bottom padding reserved for elements of the keyguard measuring notifications
private float mKeyguardNotificationBottomPadding;
+ /**
+ * The top padding from where notification should start in lockscreen.
+ * Should be static also during animations and should match the Y of the first notification.
+ */
+ private float mKeyguardNotificationTopPadding;
// Current max allowed keyguard notifications determined by measuring the panel
private int mMaxAllowedKeyguardNotifications;
@@ -653,6 +664,8 @@
private final NotificationListContainer mNotificationListContainer;
private final NotificationStackSizeCalculator mNotificationStackSizeCalculator;
+ private final NPVCDownEventState.Buffer mLastDownEvents;
+
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
@@ -755,7 +768,8 @@
PanelEventsEmitter panelEventsEmitter,
NotificationStackSizeCalculator notificationStackSizeCalculator,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
- ShadeTransitionController shadeTransitionController) {
+ ShadeTransitionController shadeTransitionController,
+ SystemClock systemClock) {
super(view,
falsingManager,
dozeLog,
@@ -771,7 +785,8 @@
panelExpansionStateManager,
ambientState,
interactionJankMonitor,
- keyguardUnlockAnimationController);
+ keyguardUnlockAnimationController,
+ systemClock);
mView = view;
mVibratorHelper = vibratorHelper;
mKeyguardMediaController = keyguardMediaController;
@@ -860,6 +875,7 @@
mScreenOffAnimationController = screenOffAnimationController;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mRemoteInputManager = remoteInputManager;
+ mLastDownEvents = new NPVCDownEventState.Buffer(MAX_DOWN_EVENT_BUFFER_SIZE);
int currentMode = navigationModeController.addListener(
mode -> mIsGestureNavigation = QuickStepContract.isGesturalMode(mode));
@@ -926,7 +942,7 @@
// the launcher icons animation starts, so use that as our
// duration.
.setDuration(unlockAnimationStartDelay)
- .setInterpolator(EMPHASIZED_DECELERATE)
+ .setInterpolator(EMPHASIZED_ACCELERATE)
.withEndAction(() -> {
instantCollapse();
mView.setAlpha(1f);
@@ -1503,7 +1519,10 @@
*/
@VisibleForTesting
float getSpaceForLockscreenNotifications() {
- float topPadding = mNotificationStackScrollLayoutController.getTopPadding();
+ float staticTopPadding = mClockPositionAlgorithm.getLockscreenMinStackScrollerPadding()
+ // getMinStackScrollerPadding is from the top of the screen,
+ // but we need it from the top of the NSSL.
+ - mNotificationStackScrollLayoutController.getTop();
// Space between bottom of notifications and top of lock icon or udfps background.
float lockIconPadding = mLockIconViewController.getTop();
@@ -1515,11 +1534,15 @@
float bottomPadding = Math.max(lockIconPadding,
Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding));
- mKeyguardNotificationBottomPadding = bottomPadding;
+ mKeyguardNotificationBottomPadding = bottomPadding;
+ mKeyguardNotificationTopPadding = staticTopPadding;
+
+ // To debug the available space, enable debug lines in this class. If you change how the
+ // available space is calculated, please also update those lines.
float availableSpace =
mNotificationStackScrollLayoutController.getHeight()
- - topPadding
+ - staticTopPadding
- bottomPadding;
return availableSpace;
}
@@ -1709,6 +1732,7 @@
}
private boolean onQsIntercept(MotionEvent event) {
+ if (DEBUG) Log.d(TAG, "onQsIntercept");
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -1763,6 +1787,7 @@
if ((h > getTouchSlop(event) || (h < -getTouchSlop(event) && mQsExpanded))
&& Math.abs(h) > Math.abs(x - mInitialTouchX)
&& shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
+ if (DEBUG) Log.d(TAG, "onQsIntercept - start tracking expansion");
mView.getParent().requestDisallowInterceptTouchEvent(true);
mQsTracking = true;
traceQsJank(true /* startTracing */, false /* wasCancelled */);
@@ -1832,6 +1857,19 @@
// down but not synthesized motion event.
mLastEventSynthesizedDown = false;
}
+ mLastDownEvents.insert(
+ mSystemClock.currentTimeMillis(),
+ mDownX,
+ mDownY,
+ mQsTouchAboveFalsingThreshold,
+ mDozingOnDown,
+ mCollapsedOnDown,
+ mIsPanelCollapseOnQQS,
+ mListenForHeadsUp,
+ mAllowExpandForSmallExpansion,
+ mTouchSlopExceededBeforeDown,
+ mLastEventSynthesizedDown
+ );
} else {
// not down event at all.
mLastEventSynthesizedDown = false;
@@ -1925,7 +1963,7 @@
if (mAllowExpandForSmallExpansion) {
// When we get a touch that came over from launcher, the velocity isn't always correct
// Let's err on expanding if the gesture has been reasonably slow
- long timeSinceDown = SystemClock.uptimeMillis() - mDownTime;
+ long timeSinceDown = mSystemClock.uptimeMillis() - mDownTime;
return timeSinceDown <= MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER;
}
return false;
@@ -1952,8 +1990,8 @@
mConflictingQsExpansionGesture = true;
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
- mInitialTouchY = event.getX();
- mInitialTouchX = event.getY();
+ mInitialTouchY = event.getY();
+ mInitialTouchX = event.getX();
}
if (!isFullyCollapsed()) {
handleQsDown(event);
@@ -2026,12 +2064,13 @@
private void handleQsDown(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept(
event.getX(), event.getY(), -1)) {
+ if (DEBUG) Log.d(TAG, "handleQsDown");
mFalsingCollector.onQsDown();
mQsTracking = true;
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
- mInitialTouchY = event.getX();
- mInitialTouchX = event.getY();
+ mInitialTouchY = event.getY();
+ mInitialTouchX = event.getX();
// If we interrupt an expansion gesture here, make sure to update the state correctly.
notifyExpandingFinished();
@@ -2139,6 +2178,7 @@
break;
case MotionEvent.ACTION_MOVE:
+ if (DEBUG) Log.d(TAG, "onQSTouch move");
setQsExpansion(h + mInitialHeightOnTouch);
if (h >= getFalsingThreshold()) {
mQsTouchAboveFalsingThreshold = true;
@@ -3170,6 +3210,8 @@
updateTrackingHeadsUp(null);
mExpandingFromHeadsUp = false;
setPanelScrimMinFraction(0.0f);
+ // Reset status bar alpha so alpha can be calculated upon updating view state.
+ setKeyguardStatusBarAlpha(-1f);
}
private void updateTrackingHeadsUp(@Nullable ExpandableNotificationRow pickedChild) {
@@ -3872,10 +3914,18 @@
@Override
public void dump(PrintWriter pw, String[] args) {
super.dump(pw, args);
- pw.println(" gestureExclusionRect: " + calculateGestureExclusionRect()
- + " applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom
- + ") qsVisible(" + mQsVisible
- );
+ IndentingPrintWriter ipw = asIndenting(pw);
+ ipw.increaseIndent();
+ ipw.println("gestureExclusionRect:" + calculateGestureExclusionRect());
+ ipw.println("applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom
+ + ")");
+ ipw.println("qsVisible:" + mQsVisible);
+ new DumpsysTableLogger(
+ TAG,
+ NPVCDownEventState.TABLE_HEADERS,
+ mLastDownEvents.toList()
+ ).printTableData(ipw);
+ ipw.decreaseIndent();
if (mKeyguardStatusBarViewController != null) {
mKeyguardStatusBarViewController.dump(pw, args);
}
@@ -4042,6 +4092,7 @@
}
if (!isFullyCollapsed() && onQsIntercept(event)) {
+ if (DEBUG) Log.d(TAG, "onQsIntercept true");
return true;
}
return super.onInterceptTouchEvent(event);
@@ -4112,6 +4163,7 @@
handled |= mHeadsUpTouchHelper.onTouchEvent(event);
if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
+ if (DEBUG) Log.d(TAG, "handleQsTouch true");
return true;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -4886,6 +4938,20 @@
drawDebugInfo(canvas, (int) mLockIconViewController.getTop(), Color.GRAY,
"mLockIconViewController.getTop()");
+ if (mKeyguardShowing) {
+ // Notifications have the space between those two lines.
+ drawDebugInfo(canvas,
+ mNotificationStackScrollLayoutController.getTop() +
+ (int) mKeyguardNotificationTopPadding,
+ Color.RED,
+ "NSSL.getTop() + mKeyguardNotificationTopPadding");
+
+ drawDebugInfo(canvas, mNotificationStackScrollLayoutController.getBottom() -
+ (int) mKeyguardNotificationBottomPadding,
+ Color.RED,
+ "NSSL.getBottom() - mKeyguardNotificationBottomPadding");
+ }
+
mDebugPaint.setColor(Color.CYAN);
canvas.drawLine(0, mClockPositionResult.stackScrollerPadding, mView.getWidth(),
mNotificationStackScrollLayoutController.getTopPadding(), mDebugPaint);
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 24660b2..faae4bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -111,7 +111,6 @@
private final SysuiColorExtractor mColorExtractor;
private final ScreenOffAnimationController mScreenOffAnimationController;
- private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
/**
* Layout params would be aggregated and dispatched all at once if this is > 0.
*
@@ -266,12 +265,6 @@
mScreenBrightnessDoze = value / 255f;
}
- @Override
- public void setFaceAuthDisplayBrightness(float brightness) {
- mFaceAuthDisplayBrightness = brightness;
- apply(mCurrentState);
- }
-
private void setKeyguardDark(boolean dark) {
int vis = mNotificationShadeView.getSystemUiVisibility();
if (dark) {
@@ -340,7 +333,7 @@
}
private void adjustScreenOrientation(State state) {
- if (state.isKeyguardShowingAndNotOccluded() || state.mDozing) {
+ if (state.mBouncerShowing || state.isKeyguardShowingAndNotOccluded() || state.mDozing) {
if (mKeyguardStateController.isKeyguardScreenRotationAllowed()) {
mLpChanged.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
} else {
@@ -455,7 +448,9 @@
private void applyWindowLayoutParams() {
if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) {
+ Trace.beginSection("updateViewLayout");
mWindowManager.updateViewLayout(mNotificationShadeView, mLp);
+ Trace.endSection();
}
}
@@ -523,7 +518,7 @@
if (state.mForceDozeBrightness) {
mLpChanged.screenBrightness = mScreenBrightnessDoze;
} else {
- mLpChanged.screenBrightness = mFaceAuthDisplayBrightness;
+ mLpChanged.screenBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
}
}
@@ -572,6 +567,10 @@
@Override
public void setPanelVisible(boolean visible) {
+ if (mCurrentState.mPanelVisible == visible
+ && mCurrentState.mNotificationShadeFocusable == visible) {
+ return;
+ }
mCurrentState.mPanelVisible = visible;
mCurrentState.mNotificationShadeFocusable = visible;
apply(mCurrentState);
@@ -626,8 +625,14 @@
@Override
public void setScrimsVisibility(int scrimsVisibility) {
+ if (scrimsVisibility == mCurrentState.mScrimsVisibility) {
+ return;
+ }
+ boolean wasExpanded = isExpanded(mCurrentState);
mCurrentState.mScrimsVisibility = scrimsVisibility;
- apply(mCurrentState);
+ if (wasExpanded != isExpanded(mCurrentState)) {
+ apply(mCurrentState);
+ }
mScrimsVisibilityListener.accept(scrimsVisibility);
}
@@ -687,6 +692,9 @@
@Override
public void setPanelExpanded(boolean isExpanded) {
+ if (mCurrentState.mPanelExpanded == isExpanded) {
+ return;
+ }
mCurrentState.mPanelExpanded = isExpanded;
apply(mCurrentState);
}
@@ -703,6 +711,9 @@
*/
@Override
public void setForceDozeBrightness(boolean forceDozeBrightness) {
+ if (mCurrentState.mForceDozeBrightness == forceDozeBrightness) {
+ return;
+ }
mCurrentState.mForceDozeBrightness = forceDozeBrightness;
apply(mCurrentState);
}
@@ -841,7 +852,6 @@
boolean mLightRevealScrimOpaque;
boolean mForceCollapsed;
boolean mForceDozeBrightness;
- int mFaceAuthDisplayBrightness;
boolean mForceUserActivity;
boolean mLaunchingActivity;
boolean mBackdropShowing;
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 6637394..7ab944d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -32,7 +32,6 @@
import android.animation.ValueAnimator;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.os.SystemClock;
import android.os.VibrationEffect;
import android.util.Log;
import android.util.MathUtils;
@@ -63,6 +62,7 @@
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
import java.io.PrintWriter;
@@ -194,6 +194,7 @@
private final PanelExpansionStateManager mPanelExpansionStateManager;
private final TouchHandler mTouchHandler;
private final InteractionJankMonitor mInteractionJankMonitor;
+ protected final SystemClock mSystemClock;
protected abstract void onExpandingFinished();
@@ -237,7 +238,8 @@
PanelExpansionStateManager panelExpansionStateManager,
AmbientState ambientState,
InteractionJankMonitor interactionJankMonitor,
- KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+ KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+ SystemClock systemClock) {
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
@@ -297,6 +299,7 @@
mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation);
mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
mInteractionJankMonitor = interactionJankMonitor;
+ mSystemClock = systemClock;
}
protected void loadDimens() {
@@ -1228,7 +1231,7 @@
mCentralSurfaces.userActivity();
mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
mMinExpandHeight = 0.0f;
- mDownTime = SystemClock.uptimeMillis();
+ mDownTime = mSystemClock.uptimeMillis();
if (mAnimatingOnDown && mClosing && !mHintAnimationRunning) {
cancelHeightAnimator();
mTouchSlopExceeded = true;
@@ -1341,7 +1344,7 @@
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mMotionAborted = false;
- mDownTime = SystemClock.uptimeMillis();
+ mDownTime = mSystemClock.uptimeMillis();
mTouchAboveFalsingThreshold = false;
mCollapsedAndHeadsUpOnDown =
isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 935f87d..c1d0769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -175,28 +175,36 @@
.setDuration(duration.toLong())
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.alpha(1f)
+ .withEndAction {
+ aodUiAnimationPlaying = false
+
+ // Lock the keyguard if it was waiting for the screen off animation to end.
+ keyguardViewMediatorLazy.get().maybeHandlePendingLock()
+
+ // Tell the CentralSurfaces to become keyguard for real - we waited on that
+ // since it is slow and would have caused the animation to jank.
+ mCentralSurfaces.updateIsKeyguard()
+
+ // Run the callback given to us by the KeyguardVisibilityHelper.
+ after.run()
+
+ // Done going to sleep, reset this flag.
+ decidedToAnimateGoingToSleep = null
+
+ // We need to unset the listener. These are persistent for future animators
+ keyguardView.animate().setListener(null)
+ interactionJankMonitor.end(CUJ_SCREEN_OFF_SHOW_AOD)
+ }
.setListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator?) {
- aodUiAnimationPlaying = false
-
- // Lock the keyguard if it was waiting for the screen off animation to end.
- keyguardViewMediatorLazy.get().maybeHandlePendingLock()
-
- // Tell the CentralSurfaces to become keyguard for real - we waited on that
- // since it is slow and would have caused the animation to jank.
- mCentralSurfaces.updateIsKeyguard()
-
- // Run the callback given to us by the KeyguardVisibilityHelper.
- after.run()
-
- // Done going to sleep, reset this flag.
- decidedToAnimateGoingToSleep = null
- // We need to unset the listener. These are persistent for future animators
- keyguardView.animate().setListener(null)
- interactionJankMonitor.end(CUJ_SCREEN_OFF_SHOW_AOD)
- }
-
override fun onAnimationCancel(animation: Animator?) {
+ // If we're cancelled, reset state flags/listeners. The end action above
+ // will not be called, which is what we want since that will finish the
+ // screen off animation and show the lockscreen, which we don't want if we
+ // were cancelled.
+ aodUiAnimationPlaying = false
+ decidedToAnimateGoingToSleep = null
+ keyguardView.animate().setListener(null)
+
interactionJankMonitor.cancel(CUJ_SCREEN_OFF_SHOW_AOD)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
index 1e73d59..eb08f37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyController.java
@@ -37,6 +37,11 @@
void suppressSensorPrivacyReminders(int sensor, boolean suppress);
+ /**
+ * @return whether lock screen authentication is required to change the toggle state
+ */
+ boolean requiresAuthentication();
+
interface Callback {
void onSensorBlockedChanged(@Sensor int sensor, boolean blocked);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
index e4c444d..fffd839 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IndividualSensorPrivacyControllerImpl.java
@@ -37,6 +37,7 @@
private final @NonNull SensorPrivacyManager mSensorPrivacyManager;
private final SparseBooleanArray mSoftwareToggleState = new SparseBooleanArray();
private final SparseBooleanArray mHardwareToggleState = new SparseBooleanArray();
+ private Boolean mRequiresAuthentication;
private final Set<Callback> mCallbacks = new ArraySet<>();
public IndividualSensorPrivacyControllerImpl(
@@ -96,6 +97,11 @@
}
@Override
+ public boolean requiresAuthentication() {
+ return mSensorPrivacyManager.requiresAuthentication();
+ }
+
+ @Override
public void addCallback(@NonNull Callback listener) {
mCallbacks.add(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
index 233778d..15ee553 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
@@ -46,6 +46,11 @@
boolean isShowing();
/**
+ * Whether the bouncer (PIN/password entry) is currently visible.
+ */
+ boolean isBouncerShowing();
+
+ /**
* If swiping up will unlock without asking for a password.
* @see #isUnlocked()
*/
@@ -186,6 +191,8 @@
default void notifyKeyguardDoneFading() {}
/** **/
default void notifyKeyguardState(boolean showing, boolean occluded) {}
+ /** **/
+ default void notifyBouncerShowing(boolean showing) {}
/**
* Updates the keyguard state to reflect that it's in the process of being dismissed, either by
@@ -231,6 +238,11 @@
default void onKeyguardShowingChanged() {}
/**
+ * Called when the bouncer (PIN/password entry) is shown or hidden.
+ */
+ default void onBouncerShowingChanged() {}
+
+ /**
* Triggered when the device was just unlocked and the lock screen is being dismissed.
*/
default void onKeyguardFadingAwayChanged() {}
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 be5da37..77e285d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -63,6 +63,7 @@
private boolean mCanDismissLockScreen;
private boolean mShowing;
+ private boolean mBouncerShowing;
private boolean mSecure;
private boolean mOccluded;
@@ -153,6 +154,11 @@
}
@Override
+ public boolean isBouncerShowing() {
+ return mBouncerShowing;
+ }
+
+ @Override
public boolean isMethodSecure() {
return mSecure;
}
@@ -328,6 +334,15 @@
}
@Override
+ public void notifyBouncerShowing(boolean showing) {
+ if (mBouncerShowing != showing) {
+ mBouncerShowing = showing;
+
+ new ArrayList<>(mCallbacks).forEach(Callback::onBouncerShowingChanged);
+ }
+ }
+
+ @Override
public void notifyPanelFlingEnd() {
mFlingingToDismissKeyguard = false;
mFlingingToDismissKeyguardDuringSwipeGesture = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index f26176c..f8c36dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -86,7 +86,6 @@
private boolean mShouldDisplayAllAccesses;
private boolean mShowSystemAccessesFlag;
private boolean mShowSystemAccessesSetting;
- private boolean mExperimentStarted;
@Inject
public LocationControllerImpl(Context context, AppOpsController appOpsController,
@@ -108,9 +107,6 @@
mShouldDisplayAllAccesses = getAllAccessesSetting();
mShowSystemAccessesFlag = getShowSystemFlag();
mShowSystemAccessesSetting = getShowSystemSetting();
- mExperimentStarted = getExperimentStarted();
- toggleSystemSettingIfExperimentJustStarted();
-
mContentObserver = new ContentObserver(mBackgroundHandler) {
@Override
public void onChange(boolean selfChange) {
@@ -127,15 +123,8 @@
DeviceConfig.NAMESPACE_PRIVACY,
backgroundHandler::post,
properties -> {
- // Update the Device Config flag which controls the experiment to display
- // location accesses.
mShouldDisplayAllAccesses = getAllAccessesSetting();
- // Update the Device Config flag which controls the experiment to display
- // system location accesses.
- mShowSystemAccessesFlag = getShowSystemFlag();
- // Update the local flag for the system accesses experiment and potentially
- // update the behavior based on the flag value.
- toggleSystemSettingIfExperimentJustStarted();
+ mShowSystemAccessesFlag = getShowSystemSetting();
updateActiveLocationRequests();
});
@@ -234,33 +223,6 @@
UserHandle.USER_CURRENT) == 1;
}
- private boolean getExperimentStarted() {
- return mSecureSettings
- .getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 0) == 1;
- }
-
- private void toggleSystemSettingIfExperimentJustStarted() {
- // mShowSystemAccessesFlag indicates whether the Device Config flag is flipped
- // by an experiment. mExperimentStarted is the local device value which indicates the last
- // value the device has seen for the Device Config flag.
- // The local device value is needed to determine that the Device Config flag was just
- // flipped, as the experiment behavior should only happen once after the experiment is
- // enabled.
- if (mShowSystemAccessesFlag && !mExperimentStarted) {
- // If the Device Config flag is enabled, but the local device setting is not then the
- // experiment just started. Update the local flag to match and enable the experiment
- // behavior by flipping the show system setting value.
- mSecureSettings.putInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 1);
- mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 1);
- mExperimentStarted = true;
- } else if (!mShowSystemAccessesFlag && mExperimentStarted) {
- // If the Device Config flag is disabled, but the local device flag is enabled then
- // update the local device flag to match.
- mSecureSettings.putInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED, 0);
- mExperimentStarted = false;
- }
- }
-
/**
* Returns true if there currently exist active high power location requests.
*/
@@ -288,6 +250,7 @@
}
boolean hadActiveLocationRequests = mAreActiveLocationRequests;
boolean shouldDisplay = false;
+ boolean showSystem = mShowSystemAccessesFlag || mShowSystemAccessesSetting;
boolean systemAppOp = false;
boolean nonSystemAppOp = false;
boolean isSystemApp;
@@ -305,7 +268,7 @@
nonSystemAppOp = true;
}
- shouldDisplay = mShowSystemAccessesSetting || shouldDisplay || !isSystemApp;
+ shouldDisplay = showSystem || shouldDisplay || !isSystemApp;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 3751721..5a33603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -269,8 +269,12 @@
super.onEnd(animation);
if (animation.getTypeMask() == WindowInsets.Type.ime()) {
mEntry.mRemoteEditImeAnimatingAway = false;
- mEntry.mRemoteEditImeVisible =
- mEditText.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
+ WindowInsets editTextRootWindowInsets = mEditText.getRootWindowInsets();
+ if (editTextRootWindowInsets == null) {
+ Log.w(TAG, "onEnd called on detached view", new Exception());
+ }
+ mEntry.mRemoteEditImeVisible = editTextRootWindowInsets != null
+ && editTextRootWindowInsets.isVisible(WindowInsets.Type.ime());
if (!mEntry.mRemoteEditImeVisible && !mEditText.mShowImeOnInputConnection) {
mController.removeRemoteInput(mEntry, mToken);
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index a50d3d6..7920d388 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -474,7 +474,7 @@
mThemeStyle = fetchThemeStyleFromSetting();
mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
- if (colorSchemeIsApplied() && !forceReload) {
+ if (colorSchemeIsApplied()) {
Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index b7f90a4..4685c14 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -38,7 +38,6 @@
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
-import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.qs.dagger.QSModule;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
@@ -102,9 +101,6 @@
}
@Binds
- abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
-
- @Binds
abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index 3329eab..ad73491 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -71,6 +71,11 @@
private var popupMenu: UserSwitcherPopupMenu? = null
private lateinit var addButton: View
private var addUserRecords = mutableListOf<UserRecord>()
+ private val userSwitchedCallback: UserTracker.Callback = object : UserTracker.Callback {
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ finish()
+ }
+ }
// When the add users options become available, insert another option to manage users
private val manageUserRecord = UserRecord(
null /* info */,
@@ -215,11 +220,7 @@
initBroadcastReceiver()
parent.post { buildUserViews() }
- userTracker.addCallback(object : UserTracker.Callback {
- override fun onUserChanged(newUser: Int, userContext: Context) {
- finish()
- }
- }, mainExecutor)
+ userTracker.addCallback(userSwitchedCallback, mainExecutor)
}
private fun showPopupMenu() {
@@ -340,6 +341,7 @@
super.onDestroy()
broadcastDispatcher.unregisterReceiver(broadcastReceiver)
+ userTracker.removeCallback(userSwitchedCallback)
}
private fun initBroadcastReceiver() {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 5b5dca3..d54de3fa 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -21,9 +21,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.provider.Settings;
-import android.view.ContextThemeWrapper;
import android.view.DisplayCutout;
import com.android.internal.policy.SystemBarUtils;
@@ -35,6 +33,8 @@
public class Utils {
+ private static Boolean sUseQsMediaPlayer = null;
+
/**
* Allows lambda iteration over a list. It is done in reverse order so it is safe
* to add or remove items during the iteration. Skips over null items.
@@ -81,9 +81,16 @@
* Off by default, but can be disabled by setting to 0
*/
public static boolean useQsMediaPlayer(Context context) {
- int flag = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
- return flag > 0;
+ // TODO(b/192412820): Replace SHOW_MEDIA_ON_QUICK_SETTINGS with compile-time value
+ // Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS can't be toggled at runtime, so simply
+ // cache the first result we fetch and use that going forward. Do this to avoid unnecessary
+ // binder calls which may happen on the critical path.
+ if (sUseQsMediaPlayer == null) {
+ int flag = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1);
+ sUseQsMediaPlayer = flag > 0;
+ }
+ return sUseQsMediaPlayer;
}
/**
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 acff871..ebdddbf 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -180,7 +180,7 @@
int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
GetWalletCardsRequest request =
new GetWalletCardsRequest(cardWidth, cardHeight, iconSizePx, /* maxCards= */ 1);
- mQuickAccessWalletClient.getWalletCards(mExecutor, request, cardsRetriever);
+ mQuickAccessWalletClient.getWalletCards(mCallbackExecutor, request, cardsRetriever);
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 7476490..39cc34b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -18,6 +18,7 @@
import android.content.ContentResolver
import android.database.ContentObserver
+import android.hardware.biometrics.BiometricFaceConstants
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
@@ -44,18 +45,20 @@
private val fakeWakeUri = Uri.Builder().appendPath("wake").build()
private val fakeUnlockIntentUri = Uri.Builder().appendPath("unlock-intent").build()
private val fakeBioFailUri = Uri.Builder().appendPath("bio-fail").build()
+ private val fakeFaceErrorsUri = Uri.Builder().appendPath("face-errors").build()
+ private val fakeFaceAcquiredUri = Uri.Builder().appendPath("face-acquired").build()
+ private val fakeUnlockIntentBioEnroll = Uri.Builder().appendPath("unlock-intent-bio").build()
@Mock
private lateinit var secureSettings: SecureSettings
-
@Mock
private lateinit var contentResolver: ContentResolver
-
@Mock
private lateinit var handler: Handler
-
@Mock
private lateinit var dumpManager: DumpManager
+ @Mock
+ private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Captor
private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
@@ -72,6 +75,13 @@
.thenReturn(fakeUnlockIntentUri)
`when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
.thenReturn(fakeBioFailUri)
+ `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS))
+ .thenReturn(fakeFaceErrorsUri)
+ `when`(secureSettings.getUriFor(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO))
+ .thenReturn(fakeFaceAcquiredUri)
+ `when`(secureSettings.getUriFor(
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED))
+ .thenReturn(fakeUnlockIntentBioEnroll)
activeUnlockConfig = ActiveUnlockConfig(
handler,
@@ -99,12 +109,7 @@
// WHEN unlock on wake is allowed
`when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
0, 0)).thenReturn(1)
- settingsObserverCaptor.value.onChange(
- false,
- listOf(fakeWakeUri),
- 0,
- 0
- )
+ updateSetting(fakeWakeUri)
// THEN active unlock triggers allowed on: wake, unlock-intent, and biometric failure
assertTrue(
@@ -134,12 +139,7 @@
// WHEN unlock on biometric failed is allowed
`when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
0, 0)).thenReturn(1)
- settingsObserverCaptor.value.onChange(
- false,
- listOf(fakeUnlockIntentUri),
- 0,
- 0
- )
+ updateSetting(fakeUnlockIntentUri)
// THEN active unlock triggers allowed on: biometric failure ONLY
assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
@@ -154,19 +154,19 @@
fun testOnBioFailSettingChanged() {
verifyRegisterSettingObserver()
- // GIVEN no active unlock settings enabled
+ // GIVEN no active unlock settings enabled and triggering unlock intent on biometric
+ // enrollment setting is disabled (empty string is disabled, null would use the default)
+ `when`(secureSettings.getStringForUser(
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+ 0)).thenReturn("")
+ updateSetting(fakeUnlockIntentBioEnroll)
assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
// WHEN unlock on biometric failed is allowed
`when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
0, 0)).thenReturn(1)
- settingsObserverCaptor.value.onChange(
- false,
- listOf(fakeBioFailUri),
- 0,
- 0
- )
+ updateSetting(fakeBioFailUri)
// THEN active unlock triggers allowed on: biometric failure ONLY
assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
@@ -177,21 +177,146 @@
ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
}
+ @Test
+ fun testFaceErrorSettingsChanged() {
+ verifyRegisterSettingObserver()
+
+ // GIVEN unlock on biometric fail
+ `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
+ 0, 0)).thenReturn(1)
+ updateSetting(fakeBioFailUri)
+
+ // WHEN face error timeout (3), allow trigger active unlock
+ `when`(secureSettings.getStringForUser(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS,
+ 0)).thenReturn("3")
+ updateSetting(fakeFaceAcquiredUri)
+
+ // THEN active unlock triggers allowed on error TIMEOUT
+ assertTrue(activeUnlockConfig.shouldRequestActiveUnlockOnFaceError(
+ BiometricFaceConstants.FACE_ERROR_TIMEOUT))
+
+ assertFalse(activeUnlockConfig.shouldRequestActiveUnlockOnFaceError(
+ BiometricFaceConstants.FACE_ERROR_CANCELED))
+ }
+
+ @Test
+ fun testFaceAcquiredSettingsChanged() {
+ verifyRegisterSettingObserver()
+
+ // GIVEN unlock on biometric fail
+ `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
+ 0, 0)).thenReturn(1)
+ updateSetting(fakeBioFailUri)
+
+ // WHEN face acquiredMsg DARK_GLASSESand MOUTH_COVERING are allowed to trigger
+ `when`(secureSettings.getStringForUser(Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
+ 0)).thenReturn(
+ "${BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED}" +
+ "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}")
+ updateSetting(fakeFaceAcquiredUri)
+
+ // THEN active unlock triggers allowed on acquired messages DARK_GLASSES & MOUTH_COVERING
+ assertTrue(activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
+ BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED))
+ assertTrue(activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
+ BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED))
+
+ assertFalse(activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
+ BiometricFaceConstants.FACE_ACQUIRED_GOOD))
+ assertFalse(activeUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
+ BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED))
+ }
+
+ @Test
+ fun testTriggerOnUnlockIntentWhenBiometricEnrolledNone() {
+ verifyRegisterSettingObserver()
+
+ // GIVEN unlock on biometric fail
+ `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
+ 0, 0)).thenReturn(1)
+ updateSetting(fakeBioFailUri)
+
+ // GIVEN fingerprint and face are NOT enrolled
+ activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor
+ `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(false)
+ `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(false)
+
+ // WHEN unlock intent is allowed when NO biometrics are enrolled (0)
+ `when`(secureSettings.getStringForUser(
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+ 0)).thenReturn("${ActiveUnlockConfig.BIOMETRIC_TYPE_NONE}")
+ updateSetting(fakeUnlockIntentBioEnroll)
+
+ // THEN active unlock triggers allowed on unlock intent
+ assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+ }
+
+ @Test
+ fun testTriggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnly() {
+ verifyRegisterSettingObserver()
+
+ // GIVEN unlock on biometric fail
+ `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
+ 0, 0)).thenReturn(1)
+ updateSetting(fakeBioFailUri)
+
+ // GIVEN fingerprint and face are both enrolled
+ activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor
+ `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true)
+ `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(true)
+
+ // WHEN unlock intent is allowed when ONLY fingerprint is enrolled or NO biometircs
+ // are enrolled
+ `when`(secureSettings.getStringForUser(
+ Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+ 0)).thenReturn(
+ "${ActiveUnlockConfig.BIOMETRIC_TYPE_ANY_FACE}" +
+ "|${ActiveUnlockConfig.BIOMETRIC_TYPE_ANY_FINGERPRINT}")
+ updateSetting(fakeUnlockIntentBioEnroll)
+
+ // THEN active unlock triggers NOT allowed on unlock intent
+ assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+
+ // WHEN fingerprint ONLY enrolled
+ `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(false)
+ `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(true)
+
+ // THEN active unlock triggers allowed on unlock intent
+ assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+
+ // WHEN face ONLY enrolled
+ `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true)
+ `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(false)
+
+ // THEN active unlock triggers allowed on unlock intent
+ assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+ }
+
+ private fun updateSetting(uri: Uri) {
+ settingsObserverCaptor.value.onChange(
+ false,
+ listOf(uri),
+ 0,
+ 0 /* flags */
+ )
+ }
+
private fun verifyRegisterSettingObserver() {
- verify(contentResolver).registerContentObserver(
- eq(fakeWakeUri),
- eq(false),
- capture(settingsObserverCaptor),
- eq(UserHandle.USER_ALL))
+ verifyRegisterSettingObserver(fakeWakeUri)
+ verifyRegisterSettingObserver(fakeUnlockIntentUri)
+ verifyRegisterSettingObserver(fakeBioFailUri)
+ verifyRegisterSettingObserver(fakeFaceErrorsUri)
+ verifyRegisterSettingObserver(fakeFaceAcquiredUri)
+ verifyRegisterSettingObserver(fakeUnlockIntentBioEnroll)
+ }
+ private fun verifyRegisterSettingObserver(uri: Uri) {
verify(contentResolver).registerContentObserver(
- eq(fakeUnlockIntentUri),
- eq(false),
- capture(settingsObserverCaptor),
- eq(UserHandle.USER_ALL))
-
- verify(contentResolver).registerContentObserver(
- eq(fakeBioFailUri),
+ eq(uri),
eq(false),
capture(settingsObserverCaptor),
eq(UserHandle.USER_ALL))
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index aff94eb..a1e23a20 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -25,7 +25,6 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.util.concurrency.DelayableExecutor
import org.junit.Before
import org.junit.Test
@@ -63,7 +62,7 @@
@Mock
lateinit var falsingCollector: FalsingCollector
@Mock
- lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ lateinit var keyguardViewController: KeyguardViewController
@Mock
private lateinit var mKeyguardMessageArea: KeyguardMessageArea
@Mock
@@ -92,13 +91,13 @@
mainExecutor,
mContext.resources,
falsingCollector,
- statusBarKeyguardViewManager
+ keyguardViewController
)
}
@Test
fun testFocusWhenBouncerIsShown() {
- Mockito.`when`(statusBarKeyguardViewManager.isBouncerShowing).thenReturn(true)
+ Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(true)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
keyguardPasswordView.post { verify(keyguardPasswordView).requestFocus() }
@@ -106,7 +105,7 @@
@Test
fun testDoNotFocusWhenBouncerIsHidden() {
- Mockito.`when`(statusBarKeyguardViewManager.isBouncerShowing).thenReturn(false)
+ Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(false)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
verify(keyguardPasswordView, never()).requestFocus()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 7b7dfdc..4d33430 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -51,7 +51,6 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -125,7 +124,7 @@
@Mock
private SessionTracker mSessionTracker;
@Mock
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private KeyguardViewController mKeyguardViewController;
private Configuration mConfiguration;
private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
@@ -153,7 +152,7 @@
(KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
SecurityMode.Password, mLockPatternUtils, null,
mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
- null, mock(Resources.class), null, mStatusBarKeyguardViewManager);
+ null, mock(Resources.class), null, mKeyguardViewController);
mKeyguardSecurityContainerController = new KeyguardSecurityContainerController.Factory(
mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 57f3617..92c2a1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
@@ -29,6 +29,7 @@
@FingerprintSensorProperties.SensorType sensorType: Int =
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
maxEnrollmentsPerUser: Int = 1,
+ halControlsIllumination: Boolean = true,
info: List<ComponentInfoInternal> = listOf(ComponentInfoInternal("a", "b", "c", "d", "e")),
resetLockoutRequiresHardwareAuthToken: Boolean = false
) = FingerprintSensorPropertiesInternal(
@@ -37,6 +38,7 @@
maxEnrollmentsPerUser,
info,
sensorType,
+ halControlsIllumination,
resetLockoutRequiresHardwareAuthToken,
listOf(this)
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
index 102f37c..dec2b82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -185,6 +185,7 @@
5 /* maxEnrollmentsPerUser */,
listOf() /* componentInfo */,
FingerprintSensorProperties.TYPE_POWER_BUTTON,
+ true /* halControlsIllumination */,
true /* resetLockoutRequiresHardwareAuthToken */,
locations
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index a57b011..fc5ccbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -65,6 +65,7 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
+private const val HAL_CONTROLS_ILLUMINATION = true
private const val REQUEST_ID = 2L
// Dimensions for the current display resolution.
@@ -129,8 +130,8 @@
statusBarStateController, panelExpansionStateManager, statusBarKeyguardViewManager,
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
configurationController, systemClock, keyguardStateController,
- unlockedScreenOffAnimationController, hbmProvider, REQUEST_ID, reason,
- controllerCallback, onTouch, activityLaunchAnimator)
+ unlockedScreenOffAnimationController, HAL_CONTROLS_ILLUMINATION, hbmProvider,
+ REQUEST_ID, reason, controllerCallback, onTouch, activityLaunchAnimator)
block()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index da5939a..87d3cd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -594,9 +594,8 @@
verify(mLatencyTracker, never()).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
// AND onIlluminatedRunnable notifies FingerprintManager about onUiReady
mOnIlluminatedRunnableCaptor.getValue().run();
- InOrder inOrder = inOrder(mFingerprintManager, mLatencyTracker);
- inOrder.verify(mFingerprintManager).onUiReady(
- eq(TEST_REQUEST_ID), eq(mUdfpsController.mSensorId));
+ InOrder inOrder = inOrder(mAlternateTouchProvider, mLatencyTracker);
+ inOrder.verify(mAlternateTouchProvider).onUiReady();
inOrder.verify(mLatencyTracker).onActionEnd(eq(LatencyTracker.ACTION_UDFPS_ILLUMINATE));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
index 27755ede..cd646c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
@@ -62,6 +62,7 @@
0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
componentInfo,
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ true /* halControlsIllumination */,
true /* resetLockoutRequiresHardwareAuthToken */,
List.of(new SensorLocationInternal("" /* displayId */,
sensorLocationX, sensorLocationY, sensorRadius)));
@@ -127,6 +128,7 @@
0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
componentInfo,
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ true /* halControlsIllumination */,
true /* resetLockoutRequiresHardwareAuthToken */,
List.of(new SensorLocationInternal("" /* displayId */,
sensorLocationX, sensorLocationY, sensorRadius)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index b87a7e7..0fdd905 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -168,7 +168,8 @@
mController.onViewAttached();
verify(mView, atLeast(1)).setPauseAuth(true);
- verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, true);
+ verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount,
+ UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN);
}
@Test
@@ -195,7 +196,8 @@
final float eased = .65f;
mStatusBarStateListener.onDozeAmountChanged(linear, eased);
- verify(mView).onDozeAmountChanged(linear, eased, true);
+ verify(mView).onDozeAmountChanged(linear, eased,
+ UdfpsKeyguardView.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 744af58..0327cfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -36,6 +36,7 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.nullable
@@ -43,7 +44,6 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
-private const val DISPLAY_ID = "" // default display id
private const val SENSOR_X = 50
private const val SENSOR_Y = 250
private const val SENSOR_RADIUS = 10
@@ -146,7 +146,7 @@
view.startIllumination(onDone)
val illuminator = withArgCaptor<Runnable> {
- verify(hbmProvider).enableHbm(capture())
+ verify(hbmProvider).enableHbm(anyBoolean(), capture())
}
assertThat(view.isIlluminationRequested).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index ae387e8..4eeb4ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -45,7 +45,6 @@
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.DozeTriggers.DozingUpdateUiEvent;
import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -91,8 +90,6 @@
private KeyguardStateController mKeyguardStateController;
@Mock
private DevicePostureController mDevicePostureController;
- @Mock
- private BatteryController mBatteryController;
private DozeTriggers mTriggers;
private FakeSensorManager mSensors;
@@ -125,7 +122,7 @@
asyncSensorManager, wakeLock, mDockManager, mProximitySensor,
mProximityCheck, mock(DozeLog.class), mBroadcastDispatcher, new FakeSettings(),
mAuthController, mExecutor, mUiEventLogger, mKeyguardStateController,
- mDevicePostureController, mBatteryController);
+ mDevicePostureController);
mTriggers.setDozeMachine(mMachine);
waitForSensorManager();
}
@@ -233,9 +230,7 @@
when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
// WHEN the pick up gesture is triggered and keyguard isn't occluded
- // and device isn't on a wireless charger
when(mKeyguardStateController.isOccluded()).thenReturn(false);
- when(mBatteryController.isPluggedInWireless()).thenReturn(false);
mTriggers.onSensor(DozeLog.REASON_SENSOR_PICKUP, 100, 100, null);
// THEN wakeup
@@ -249,22 +244,6 @@
// WHEN the pick up gesture is triggered and keyguard IS occluded
when(mKeyguardStateController.isOccluded()).thenReturn(true);
- when(mBatteryController.isPluggedInWireless()).thenReturn(false);
- mTriggers.onSensor(DozeLog.REASON_SENSOR_PICKUP, 100, 100, null);
-
- // THEN never wakeup
- verify(mMachine, never()).wakeUp();
- }
-
- @Test
- public void testPickupGestureWirelessCharger() {
- // GIVEN device is in doze (screen blank, but running doze sensors)
- when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
-
- // WHEN the pick up gesture is triggered
- // and device IS on a wireless charger
- when(mKeyguardStateController.isOccluded()).thenReturn(false);
- when(mBatteryController.isPluggedInWireless()).thenReturn(true);
mTriggers.onSensor(DozeLog.REASON_SENSOR_PICKUP, 100, 100, null);
// THEN never wakeup
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index 2d8c4d5..2abc666 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -14,6 +14,7 @@
import com.android.keyguard.KeyguardViewController
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.policy.KeyguardStateController
import junit.framework.Assert.assertEquals
@@ -49,6 +50,8 @@
private lateinit var biometricUnlockController: BiometricUnlockController
@Mock
private lateinit var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier
+ @Mock
+ private lateinit var statusBarStateController: SysuiStatusBarStateController
private lateinit var remoteAnimationTarget: RemoteAnimationTarget
@@ -57,7 +60,7 @@
MockitoAnnotations.initMocks(this)
keyguardUnlockAnimationController = KeyguardUnlockAnimationController(
context, keyguardStateController, { keyguardViewMediator }, keyguardViewController,
- featureFlags, { biometricUnlockController }
+ featureFlags, { biometricUnlockController }, statusBarStateController
)
`when`(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
index be923a6..c532ed5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java
@@ -34,8 +34,6 @@
import android.graphics.Rect;
import android.graphics.drawable.AnimatedStateListDrawable;
import android.hardware.biometrics.BiometricSourceType;
-import android.hardware.biometrics.SensorLocationInternal;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
@@ -77,9 +75,6 @@
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
-import java.util.ArrayList;
-import java.util.List;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -182,7 +177,7 @@
@Test
public void testUpdateFingerprintLocationOnInit() {
// GIVEN fp sensor location is available pre-attached
- Pair<Integer, PointF> udfps = setupUdfps(); // first = radius, second = udfps location
+ Pair<Float, PointF> udfps = setupUdfps(); // first = radius, second = udfps location
// WHEN lock icon view controller is initialized and attached
mLockIconViewController.init();
@@ -197,7 +192,7 @@
@Test
public void testUpdatePaddingBasedOnResolutionScale() {
// GIVEN fp sensor location is available pre-attached & scaled resolution factor is 5
- Pair<Integer, PointF> udfps = setupUdfps(); // first = radius, second = udfps location
+ Pair<Float, PointF> udfps = setupUdfps(); // first = radius, second = udfps location
when(mAuthController.getScaleFactor()).thenReturn(5f);
// WHEN lock icon view controller is initialized and attached
@@ -215,20 +210,19 @@
// GIVEN fp sensor location is not available pre-init
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
when(mAuthController.getFingerprintSensorLocation()).thenReturn(null);
- when(mAuthController.getUdfpsProps()).thenReturn(null);
mLockIconViewController.init();
captureAttachListener();
mAttachListener.onViewAttachedToWindow(mLockIconView);
- // GIVEN fp sensor location is available post-atttached
+ // GIVEN fp sensor location is available post-attached
captureAuthControllerCallback();
- Pair<Integer, PointF> udfps = setupUdfps();
+ Pair<Float, PointF> udfps = setupUdfps();
// WHEN all authenticators are registered
mAuthControllerCallback.onAllAuthenticatorsRegistered();
mDelayableExecutor.runAllReady();
- // THEN lock icon view location is updated with the same coordinates as fpProps
+ // THEN lock icon view location is updated with the same coordinates as auth controller vals
verify(mLockIconView).setCenterLocation(eq(udfps.second), eq(udfps.first),
eq(PADDING));
}
@@ -402,20 +396,10 @@
verify(mLockIconView).setTranslationX(0);
}
- private Pair<Integer, PointF> setupUdfps() {
+ private Pair<Float, PointF> setupUdfps() {
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
final PointF udfpsLocation = new PointF(50, 75);
- final int radius = 33;
- final FingerprintSensorPropertiesInternal fpProps =
- new FingerprintSensorPropertiesInternal(
- /* sensorId */ 0,
- /* strength */ 0,
- /* max enrollments per user */ 5,
- /* component info */ new ArrayList<>(),
- /* sensorType */ 3,
- /* resetLockoutRequiresHwToken */ false,
- List.of(new SensorLocationInternal("" /* displayId */,
- (int) udfpsLocation.x, (int) udfpsLocation.y, radius)));
+ final float radius = 33f;
when(mAuthController.getUdfpsLocation()).thenReturn(udfpsLocation);
when(mAuthController.getUdfpsRadius()).thenReturn(radius);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
index 5463977..ea841b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
@@ -50,14 +50,12 @@
private lateinit var colorSchemeTransition: ColorSchemeTransition
@Mock private lateinit var mockAnimatingTransition: AnimatingColorTransition
- @Mock private lateinit var mockGenericTransition: GenericColorTransition
@Mock private lateinit var valueAnimator: ValueAnimator
@Mock private lateinit var colorScheme: ColorScheme
@Mock private lateinit var extractColor: ExtractCB
@Mock private lateinit var applyColor: ApplyCB
private lateinit var animatingColorTransitionFactory: AnimatingColorTransitionFactory
- private lateinit var genericColorTransitionFactory: GenericColorTransitionFactory
@Mock private lateinit var mediaViewHolder: MediaViewHolder
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
@@ -65,11 +63,10 @@
@Before
fun setUp() {
animatingColorTransitionFactory = { _, _, _ -> mockAnimatingTransition }
- genericColorTransitionFactory = { _ -> mockGenericTransition }
whenever(extractColor.invoke(colorScheme)).thenReturn(TARGET_COLOR)
colorSchemeTransition = ColorSchemeTransition(
- context, mediaViewHolder, animatingColorTransitionFactory, genericColorTransitionFactory
+ context, mediaViewHolder, animatingColorTransitionFactory
)
colorTransition = object : AnimatingColorTransition(
@@ -148,8 +145,7 @@
@Test
fun testColorSchemeTransition_update() {
- colorSchemeTransition.updateColorScheme(colorScheme)
- verify(mockAnimatingTransition, times(7)).updateColorScheme(colorScheme)
- verify(mockGenericTransition).updateColorScheme(colorScheme)
+ colorSchemeTransition.updateColorScheme(colorScheme, true)
+ verify(mockAnimatingTransition, times(9)).updateColorScheme(colorScheme)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
index 1522ee8..0d917e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
@@ -122,6 +122,11 @@
playbackLocation = MediaData.PLAYBACK_CAST_REMOTE, resumption = false),
5000L)
+ val active = Triple("active",
+ DATA.copy(active = true, isPlaying = false,
+ playbackLocation = MediaData.PLAYBACK_LOCAL, resumption = true),
+ 250L)
+
val resume1 = Triple("resume 1",
DATA.copy(active = false, isPlaying = false,
playbackLocation = MediaData.PLAYBACK_LOCAL, resumption = true),
@@ -140,7 +145,7 @@
// Resume controls, by last active
val expected = listOf(playingLocal, playingCast, pausedCast, pausedLocal, playingRcn,
- pausedRcn, resume2, resume1)
+ pausedRcn, active, resume2, resume1)
expected.forEach {
clock.setCurrentTimeMillis(it.third)
@@ -173,9 +178,9 @@
MediaPlayerData.addMediaRecommendation(SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA, panel,
false, clock)
- // Then it should be shown at the end of the carousel
- val size = MediaPlayerData.playerKeys().size
- assertTrue(MediaPlayerData.playerKeys().elementAt(size - 1).isSsMediaRec)
+ // Then it should be shown at the end of the carousel's active entries
+ val idx = MediaPlayerData.playerKeys().count { it.data.active } - 1
+ assertTrue(MediaPlayerData.playerKeys().elementAt(idx).isSsMediaRec)
}
@Test
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 94254da..18aae0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -21,7 +21,6 @@
import android.app.PendingIntent
import android.app.smartspace.SmartspaceAction
import android.content.Context
-import org.mockito.Mockito.`when` as whenever
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
@@ -34,6 +33,7 @@
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.Icon
import android.graphics.drawable.RippleDrawable
+import android.graphics.drawable.TransitionDrawable
import android.media.MediaMetadata
import android.media.session.MediaSession
import android.media.session.PlaybackState
@@ -58,6 +58,7 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.media.MediaControlPanel.KEY_SMARTSPACE_APP_NAME
import com.android.systemui.media.dialog.MediaOutputDialogFactory
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
@@ -66,14 +67,15 @@
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.KotlinArgumentCaptor
-import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import dagger.Lazy
+import junit.framework.Assert.assertTrue
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -90,6 +92,7 @@
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 PACKAGE = "PKG"
@@ -100,6 +103,7 @@
private const val SESSION_ARTIST = "SESSION_ARTIST"
private const val SESSION_TITLE = "SESSION_TITLE"
private const val DISABLED_DEVICE_NAME = "DISABLED_DEVICE_NAME"
+private const val REC_APP_NAME = "REC APP NAME"
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -260,6 +264,7 @@
// Set valid recommendation data
val extras = Bundle()
+ extras.putString(KEY_SMARTSPACE_APP_NAME, REC_APP_NAME)
val intent = Intent().apply {
putExtras(extras)
setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -337,6 +342,7 @@
whenever(viewHolder.player).thenReturn(view)
whenever(viewHolder.appIcon).thenReturn(appIcon)
whenever(viewHolder.albumView).thenReturn(albumView)
+ whenever(albumView.foreground).thenReturn(mock(Drawable::class.java))
whenever(viewHolder.titleText).thenReturn(titleText)
whenever(viewHolder.artistText).thenReturn(artistText)
whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java))
@@ -535,6 +541,13 @@
}
@Test
+ fun bindAlbumView_testHardwareAfterAttach() {
+ player.attachPlayer(viewHolder)
+
+ verify(albumView).setLayerType(View.LAYER_TYPE_HARDWARE, null)
+ }
+
+ @Test
fun bindAlbumView_setAfterExecutors() {
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
@@ -579,9 +592,11 @@
player.bindPlayer(state1, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
- verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
+ val drawableCaptor = argumentCaptor<Drawable>()
+ verify(albumView, times(2)).setImageDrawable(drawableCaptor.capture())
+ assertTrue(drawableCaptor.allValues[1] is TransitionDrawable)
- // Third binding does run transition or update background
+ // Third binding doesn't run transition or update background
player.bindPlayer(state2, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
@@ -1110,6 +1125,91 @@
verify(mediaCarouselController).removePlayer(eq(mediaKey), eq(false), eq(false))
}
+ @Test
+ fun player_gutsOpen_contentDescriptionIsForGuts() {
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ player.attachPlayer(viewHolder)
+
+ val gutsTextString = "gutsText"
+ whenever(gutsText.text).thenReturn(gutsTextString)
+ player.bindPlayer(mediaData, KEY)
+
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).isEqualTo(gutsTextString)
+ }
+
+ @Test
+ fun player_gutsClosed_contentDescriptionIsForPlayer() {
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ player.attachPlayer(viewHolder)
+
+ val app = "appName"
+ player.bindPlayer(mediaData.copy(app = app), KEY)
+
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).contains(mediaData.song!!)
+ assertThat(description).contains(mediaData.artist!!)
+ assertThat(description).contains(app)
+ }
+
+ @Test
+ fun player_gutsChangesFromOpenToClosed_contentDescriptionUpdated() {
+ // Start out open
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ whenever(gutsText.text).thenReturn("gutsText")
+ player.attachPlayer(viewHolder)
+ val app = "appName"
+ player.bindPlayer(mediaData.copy(app = app), KEY)
+
+ // Update to closed by long pressing
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(viewHolder.player).onLongClickListener = captor.capture()
+ reset(viewHolder.player)
+
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ captor.value.onLongClick(viewHolder.player)
+
+ // Then content description is now the player content description
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).contains(mediaData.song!!)
+ assertThat(description).contains(mediaData.artist!!)
+ assertThat(description).contains(app)
+ }
+
+ @Test
+ fun player_gutsChangesFromClosedToOpen_contentDescriptionUpdated() {
+ // Start out closed
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ val gutsTextString = "gutsText"
+ whenever(gutsText.text).thenReturn(gutsTextString)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(mediaData.copy(app = "appName"), KEY)
+
+ // Update to open by long pressing
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(viewHolder.player).onLongClickListener = captor.capture()
+ reset(viewHolder.player)
+
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ captor.value.onLongClick(viewHolder.player)
+
+ // Then content description is now the guts content description
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).isEqualTo(gutsTextString)
+ }
+
/* ***** END guts tests for the player ***** */
/* ***** Guts tests for the recommendations ***** */
@@ -1178,6 +1278,85 @@
verify(mediaDataManager).dismissSmartspaceRecommendation(eq(mediaKey), anyLong())
}
+ @Test
+ fun recommendation_gutsOpen_contentDescriptionIsForGuts() {
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ player.attachRecommendation(recommendationViewHolder)
+
+ val gutsTextString = "gutsText"
+ whenever(gutsText.text).thenReturn(gutsTextString)
+ player.bindRecommendation(smartspaceData)
+
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).isEqualTo(gutsTextString)
+ }
+
+ @Test
+ fun recommendation_gutsClosed_contentDescriptionIsForPlayer() {
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ player.attachRecommendation(recommendationViewHolder)
+
+ player.bindRecommendation(smartspaceData)
+
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).contains(REC_APP_NAME)
+ }
+
+ @Test
+ fun recommendation_gutsChangesFromOpenToClosed_contentDescriptionUpdated() {
+ // Start out open
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ whenever(gutsText.text).thenReturn("gutsText")
+ player.attachRecommendation(recommendationViewHolder)
+ player.bindRecommendation(smartspaceData)
+
+ // Update to closed by long pressing
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(viewHolder.player).onLongClickListener = captor.capture()
+ reset(viewHolder.player)
+
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ captor.value.onLongClick(viewHolder.player)
+
+ // Then content description is now the player content description
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).contains(REC_APP_NAME)
+ }
+
+ @Test
+ fun recommendation_gutsChangesFromClosedToOpen_contentDescriptionUpdated() {
+ // Start out closed
+ whenever(mediaViewController.isGutsVisible).thenReturn(false)
+ val gutsTextString = "gutsText"
+ whenever(gutsText.text).thenReturn(gutsTextString)
+ player.attachRecommendation(recommendationViewHolder)
+ player.bindRecommendation(smartspaceData)
+
+ // Update to open by long pressing
+ val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
+ verify(viewHolder.player).onLongClickListener = captor.capture()
+ reset(viewHolder.player)
+
+ whenever(mediaViewController.isGutsVisible).thenReturn(true)
+ captor.value.onLongClick(viewHolder.player)
+
+ // Then content description is now the guts content description
+ val descriptionCaptor = ArgumentCaptor.forClass(CharSequence::class.java)
+ verify(viewHolder.player).contentDescription = descriptionCaptor.capture()
+ val description = descriptionCaptor.value.toString()
+
+ assertThat(description).isEqualTo(gutsTextString)
+ }
+
/* ***** END guts tests for the recommendations ***** */
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index 10eeb11..18ee791 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -25,19 +25,17 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
-
import com.android.settingslib.media.LocalMediaManager
import com.android.settingslib.media.MediaDevice
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
-
import com.google.common.truth.Truth.assertThat
-
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -50,8 +48,8 @@
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
private const val KEY = "TEST_KEY"
private const val KEY_OLD = "TEST_KEY_OLD"
@@ -81,6 +79,7 @@
@Mock private lateinit var route: RoutingSessionInfo
@Mock private lateinit var controller: MediaController
@Mock private lateinit var playbackInfo: PlaybackInfo
+ @Mock private lateinit var configurationController: ConfigurationController
private lateinit var session: MediaSession
private lateinit var mediaData: MediaData
@JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -94,6 +93,7 @@
lmmFactory,
mr2,
muteAwaitFactory,
+ configurationController,
fakeFgExecutor,
fakeBgExecutor,
dumpster
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt
index 604e1f3..1817809 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaViewControllerTest.kt
@@ -4,16 +4,22 @@
import android.testing.TestableLooper
import android.view.View
import androidx.test.filters.SmallTest
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.animation.MeasurementInput
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.animation.TransitionViewState
+import com.android.systemui.util.animation.WidgetState
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
/**
* Tests for {@link MediaViewController}.
@@ -31,6 +37,9 @@
private lateinit var mediaViewController: MediaViewController
private val mediaHostStateHolder = MediaHost.MediaHostStateHolder()
private var transitionLayout = TransitionLayout(context, /* attrs */ null, /* defStyleAttr */ 0)
+ @Mock private lateinit var mockViewState: TransitionViewState
+ @Mock private lateinit var mockCopiedState: TransitionViewState
+ @Mock private lateinit var mockWidgetState: WidgetState
@Before
fun setUp() {
@@ -63,4 +72,15 @@
mediaHostStateHolder.squishFraction = 0.5f
assertTrue(mediaViewController.obtainViewState(mediaHostStateHolder)!!.height == 50)
}
+
+ @Test
+ fun testSquish_DoesNotMutateViewState() {
+ whenever(mockViewState.copy()).thenReturn(mockCopiedState)
+ whenever(mockCopiedState.widgetStates)
+ .thenReturn(mutableMapOf(R.id.album_art to mockWidgetState))
+
+ mediaViewController.squishViewState(mockViewState, 0.5f)
+ verify(mockViewState, times(1)).copy()
+ verifyNoMoreInteractions(mockViewState)
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
index 06d45de..a074475 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
@@ -27,6 +27,7 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.mock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -136,6 +137,24 @@
}
@Test
+ fun testConnection_calledTwice_oldBrowserDisconnected() {
+ val oldBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)
+
+ // When testConnection can connect to the service
+ setupBrowserConnection()
+ resumeBrowser.testConnection()
+
+ // And testConnection is called again
+ val newBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(newBrowser)
+ resumeBrowser.testConnection()
+
+ // Then we disconnect the old browser
+ verify(oldBrowser).disconnect()
+ }
+
+ @Test
fun testFindRecentMedia_connectionFails_error() {
// When findRecentMedia is called and we cannot connect
setupBrowserFailed()
@@ -169,6 +188,24 @@
}
@Test
+ fun testFindRecentMedia_calledTwice_oldBrowserDisconnected() {
+ val oldBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)
+
+ // When findRecentMedia is called and we connect
+ setupBrowserConnection()
+ resumeBrowser.findRecentMedia()
+
+ // And findRecentMedia is called again
+ val newBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(newBrowser)
+ resumeBrowser.findRecentMedia()
+
+ // Then we disconnect the old browser
+ verify(oldBrowser).disconnect()
+ }
+
+ @Test
fun testFindRecentMedia_noChildren_error() {
// When findRecentMedia is called and we connect, but do not get any results
setupBrowserConnectionNoResults()
@@ -223,6 +260,24 @@
verify(transportControls).play()
}
+ @Test
+ fun testRestart_calledTwice_oldBrowserDisconnected() {
+ val oldBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(oldBrowser)
+
+ // When restart is called and we connect successfully
+ setupBrowserConnection()
+ resumeBrowser.restart()
+
+ // And restart is called again
+ val newBrowser = mock<MediaBrowser>()
+ whenever(browserFactory.create(any(), any(), any())).thenReturn(newBrowser)
+ resumeBrowser.restart()
+
+ // Then we disconnect the old browser
+ verify(oldBrowser).disconnect()
+ }
+
/**
* Helper function to mock a failed connection
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 4a740f6..a526087 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -60,6 +60,7 @@
import android.view.DisplayInfo;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
@@ -85,6 +86,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.statusbar.CommandQueue;
@@ -163,7 +165,7 @@
@Mock
private UiEventLogger mUiEventLogger;
@Mock
- EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+ private ViewTreeObserver mViewTreeObserver;
@Mock
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarHelper mNavBarHelper;
@@ -187,6 +189,8 @@
private DeadZone mDeadZone;
@Mock
private CentralSurfaces mCentralSurfaces;
+ @Mock
+ private UserContextProvider mUserContextProvider;
private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
@Rule
@@ -196,8 +200,6 @@
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
- .thenReturn(mEdgeBackGestureHandler);
when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
@@ -210,6 +212,9 @@
when(mNavigationBarTransitions.getLightTransitionsController())
.thenReturn(mLightBarTransitionsController);
when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
+ when(mNavigationBarView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+ when(mUserContextProvider.createCurrentUserContext(any(Context.class)))
+ .thenReturn(mContext);
setupSysuiDependency();
// This class inflates views that call Dependency.get, thus these injections are still
// necessary.
@@ -217,8 +222,6 @@
mDependency.injectMockDependency(KeyguardStateController.class);
mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
mDependency.injectMockDependency(NavigationBarController.class);
- mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
- mEdgeBackGestureHandlerFactory);
mDependency.injectTestDependency(OverviewProxyService.class, mOverviewProxyService);
mDependency.injectTestDependency(NavigationModeController.class, mNavigationModeController);
TestableLooper.get(this).runWithLooper(() -> {
@@ -447,7 +450,6 @@
mock(NotificationRemoteInputManager.class),
mock(NotificationShadeDepthController.class),
mHandler,
- mock(NavigationBarOverlayController.class),
mUiEventLogger,
mNavBarHelper,
mLightBarController,
@@ -459,7 +461,9 @@
mDeadZone,
mDeviceConfigProxyFake,
mNavigationBarTransitions,
- Optional.of(mock(BackAnimation.class))));
+ mEdgeBackGestureHandler,
+ Optional.of(mock(BackAnimation.class)),
+ mUserContextProvider));
}
private void processAllMessages() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index c88ceac..4f6475f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -90,6 +90,7 @@
private static final String CARD_ID = "card_id";
private static final String LABEL = "QAW";
+ private static final String CARD_DESCRIPTION = "•••• 1234";
private static final Icon CARD_IMAGE =
Icon.createWithBitmap(Bitmap.createBitmap(70, 50, Bitmap.Config.ARGB_8888));
@@ -282,9 +283,7 @@
mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_ACTIVE, state.state);
- assertEquals(
- "•••• 1234",
- state.secondaryLabel);
+ assertEquals(CARD_DESCRIPTION, state.secondaryLabel);
assertNotNull(state.stateDescription);
assertNotNull(state.sideViewCustomDrawable);
}
@@ -298,11 +297,9 @@
mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_INACTIVE, state.state);
- assertEquals(
- mContext.getString(R.string.wallet_secondary_label_device_locked),
- state.secondaryLabel);
+ assertEquals(CARD_DESCRIPTION, state.secondaryLabel);
assertNotNull(state.stateDescription);
- assertNull(state.sideViewCustomDrawable);
+ assertNotNull(state.sideViewCustomDrawable);
}
@Test
@@ -314,9 +311,7 @@
mTile.handleUpdateState(state, null);
assertEquals(Tile.STATE_ACTIVE, state.state);
- assertEquals(
- "•••• 1234",
- state.secondaryLabel);
+ assertEquals(CARD_DESCRIPTION, state.secondaryLabel);
assertNotNull(state.stateDescription);
assertNotNull(state.sideViewCustomDrawable);
}
@@ -426,6 +421,6 @@
private WalletCard createWalletCard(Context context) {
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
- return new WalletCard.Builder(CARD_ID, CARD_IMAGE, "•••• 1234", pendingIntent).build();
+ return new WalletCard.Builder(CARD_ID, CARD_IMAGE, CARD_DESCRIPTION, pendingIntent).build();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
index 540d291..1cce3b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -21,10 +21,13 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.DeviceConfigProxyFake
+import com.android.systemui.util.Utils
+import com.android.systemui.util.mockito.any
import org.junit.After
import org.junit.Assert.assertFalse
@@ -32,28 +35,33 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoSession
+import org.mockito.quality.Strictness
@RunWith(AndroidTestingRunner::class)
@SmallTest
class NotificationSectionsFeatureManagerTest : SysuiTestCase() {
var manager: NotificationSectionsFeatureManager? = null
val proxyFake = DeviceConfigProxyFake()
- var originalQsMediaPlayer: Int = 0
+ private lateinit var staticMockSession: MockitoSession
@Before
public fun setup() {
manager = NotificationSectionsFeatureManager(proxyFake, mContext)
manager!!.clearCache()
- originalQsMediaPlayer = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1)
+ staticMockSession = ExtendedMockito.mockitoSession()
+ .mockStatic<Utils>(Utils::class.java)
+ .strictness(Strictness.LENIENT)
+ .startMocking()
+ `when`(Utils.useQsMediaPlayer(any())).thenReturn(false)
Settings.Global.putInt(context.getContentResolver(),
Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 0)
}
@After
public fun teardown() {
- Settings.Global.putInt(context.getContentResolver(),
- Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, originalQsMediaPlayer)
+ staticMockSession.finishMocking()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
index b45d78d..4b458f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
@@ -88,4 +88,7 @@
return this;
}
+ public static List<NotificationEntry> getRawChildren(GroupEntry groupEntry) {
+ return groupEntry.getRawChildren();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
index 7692a05..742fcf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
@@ -21,17 +21,22 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.icon.ConversationIconManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
+import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertFalse
@@ -52,8 +57,10 @@
private lateinit var promoter: NotifPromoter
private lateinit var peopleSectioner: NotifSectioner
private lateinit var peopleComparator: NotifComparator
+ private lateinit var beforeRenderListListener: OnBeforeRenderListListener
@Mock private lateinit var pipeline: NotifPipeline
+ @Mock private lateinit var conversationIconManager: ConversationIconManager
@Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
@Mock private lateinit var channel: NotificationChannel
@Mock private lateinit var headerController: NodeController
@@ -66,7 +73,11 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- coordinator = ConversationCoordinator(peopleNotificationIdentifier, headerController)
+ coordinator = ConversationCoordinator(
+ peopleNotificationIdentifier,
+ conversationIconManager,
+ headerController
+ )
whenever(channel.isImportantConversation).thenReturn(true)
coordinator.attach(pipeline)
@@ -75,6 +86,9 @@
promoter = withArgCaptor {
verify(pipeline).addPromoter(capture())
}
+ beforeRenderListListener = withArgCaptor {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
peopleSectioner = coordinator.sectioner
peopleComparator = peopleSectioner.comparator!!
@@ -96,6 +110,25 @@
}
@Test
+ fun testPromotedImportantConversationsMakesSummaryUnimportant() {
+ val altChildA = NotificationEntryBuilder().setTag("A").build()
+ val altChildB = NotificationEntryBuilder().setTag("B").build()
+ val summary = NotificationEntryBuilder().setId(2).setChannel(channel).build()
+ val groupEntry = GroupEntryBuilder()
+ .setParent(GroupEntry.ROOT_ENTRY)
+ .setSummary(summary)
+ .setChildren(listOf(entry, altChildA, altChildB))
+ .build()
+ assertTrue(promoter.shouldPromoteToTopLevel(entry))
+ assertFalse(promoter.shouldPromoteToTopLevel(altChildA))
+ assertFalse(promoter.shouldPromoteToTopLevel(altChildB))
+ NotificationEntryBuilder.setNewParent(entry, GroupEntry.ROOT_ENTRY)
+ GroupEntryBuilder.getRawChildren(groupEntry).remove(entry)
+ beforeRenderListListener.onBeforeRenderList(listOf(entry, groupEntry))
+ verify(conversationIconManager).setUnimportantConversations(eq(listOf(summary.key)))
+ }
+
+ @Test
fun testInPeopleSection() {
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entry))
.thenReturn(TYPE_PERSON)
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 cf99607..3a85972 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
@@ -22,11 +22,14 @@
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.notification.collection.EntryUtilKt.modifyEntry;
import static com.android.systemui.util.mockito.KotlinMockitoHelpersKt.argThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -55,6 +58,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.RankingBuilder;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -90,7 +94,7 @@
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private HighPriorityProvider mHighPriorityProvider;
- @Mock private StatusBarStateController mStatusBarStateController;
+ @Mock private SysuiStatusBarStateController mStatusBarStateController;
@Mock private BroadcastDispatcher mBroadcastDispatcher;
private final FakeSettings mFakeSettings = new FakeSettings();
@@ -178,7 +182,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- callback.onStateChanged(0);
+ callback.onUpcomingStateChanged(0);
verify(listener).accept(anyString());
}
@@ -199,7 +203,7 @@
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
callback.onReceive(mContext, new Intent(Intent.ACTION_USER_SWITCHED));
verify(listener).accept(anyString());
@@ -207,7 +211,7 @@
@Test
public void notifyListeners_onSettingChange_lockScreenShowNotifs() {
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
@@ -218,7 +222,7 @@
@Test
public void notifyListeners_onSettingChange_lockScreenAllowPrivateNotifs() {
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
@@ -228,8 +232,43 @@
}
@Test
+ public void hideSilentNotificationsPerUserSettingWithHighPriorityParent() {
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false);
+ GroupEntry parent = new GroupEntryBuilder()
+ .setKey("parent")
+ .addChild(mEntry)
+ .setSummary(new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setImportance(IMPORTANCE_LOW)
+ .build())
+ .build();
+ mEntry = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setImportance(IMPORTANCE_LOW)
+ .setParent(parent)
+ .build();
+ when(mHighPriorityProvider.isHighPriority(any())).thenReturn(false);
+ assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry));
+ }
+
+ @Test
+ public void hideSilentNotificationsPerUserSetting() {
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true);
+ mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false);
+ mEntry = new NotificationEntryBuilder()
+ .setUser(new UserHandle(NOTIF_USER_ID))
+ .setImportance(IMPORTANCE_LOW)
+ .build();
+ when(mHighPriorityProvider.isHighPriority(any())).thenReturn(false);
+ assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry));
+ }
+
+ @Test
public void notifyListeners_onSettingChange_zenMode() {
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
@@ -240,7 +279,7 @@
@Test
public void notifyListeners_onSettingChange_lockScreenShowSilentNotifs() {
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
Consumer<String> listener = mock(Consumer.class);
mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener);
@@ -262,7 +301,7 @@
public void keyguardNotShowing() {
// GIVEN the lockscreen isn't showing
setupUnfilteredState(mEntry);
- when(mKeyguardStateController.isShowing()).thenReturn(false);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE);
// THEN don't filter out the entry
assertFalse(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry));
@@ -384,8 +423,8 @@
mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false);
when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true);
- // THEN don't filter out the entry
- assertFalse(
+ // THEN filter out the entry regardless of parent
+ assertTrue(
mKeyguardNotificationVisibilityProvider.shouldHideNotification(entryWithParent));
// WHEN its parent doesn't exceed threshold to show on lockscreen
@@ -404,7 +443,7 @@
*/
private void setupUnfilteredState(NotificationEntry entry) {
// keyguard is showing
- when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
// show notifications on the lockscreen
when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true);
@@ -452,11 +491,11 @@
@BindsInstance NotificationLockscreenUserManager lockscreenUserManager,
@BindsInstance KeyguardUpdateMonitor keyguardUpdateMonitor,
@BindsInstance HighPriorityProvider highPriorityProvider,
- @BindsInstance StatusBarStateController statusBarStateController,
+ @BindsInstance SysuiStatusBarStateController statusBarStateController,
@BindsInstance BroadcastDispatcher broadcastDispatcher,
@BindsInstance SecureSettings secureSettings,
@BindsInstance GlobalSettings globalSettings
);
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 4ea9321..0f2e9bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -318,15 +318,6 @@
}
@Test
- public void testGetIsNonblockable_oemLocked() throws Exception {
- ExpandableNotificationRow row =
- mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
- row.getEntry().getChannel().setImportanceLockedByOEM(true);
-
- assertTrue(row.getIsNonblockable());
- }
-
- @Test
public void testGetIsNonblockable_criticalDeviceFunction() throws Exception {
ExpandableNotificationRow row =
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 4986792..f43c2a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -160,7 +160,7 @@
@Test
public void testShow_notifiesVisibility() {
mBouncer.show(true);
- verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(true));
+ verify(mKeyguardStateController).notifyBouncerShowing(eq(true));
verify(mExpansionCallback).onStartingToShow();
// Not called again when visible
@@ -238,7 +238,7 @@
@Test
public void testHide_notifiesVisibility() {
mBouncer.hide(false);
- verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(false));
+ verify(mKeyguardStateController).notifyBouncerShowing(eq(false));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 6d3a5fe..ec20271 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -336,7 +336,7 @@
// WHEN the position algorithm is run
positionClock();
// THEN the padding DOESN'T adjust for keyguard status height.
- assertThat(mClockPositionAlgorithm.getMinStackScrollerPadding())
+ assertThat(mClockPositionAlgorithm.getLockscreenMinStackScrollerPadding())
.isEqualTo(mKeyguardStatusBarHeaderHeight);
}
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 6997b3e..11f96ce 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
@@ -139,6 +139,7 @@
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -357,10 +358,12 @@
private Handler mMainHandler;
private final PanelExpansionStateManager mPanelExpansionStateManager =
new PanelExpansionStateManager();
+ private SystemClock mSystemClock;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+ mSystemClock = new FakeSystemClock();
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
mInteractionJankMonitor);
@@ -533,7 +536,8 @@
mPanelEventsEmitter,
mNotificationStackSizeCalculator,
mUnlockedScreenOffAnimationController,
- mShadeTransitionController);
+ mShadeTransitionController,
+ mSystemClock);
mNotificationPanelViewController.initDependencies(
mCentralSurfaces,
() -> {},
@@ -606,13 +610,13 @@
when(mLockIconViewController.getTop()).thenReturn(80f);
when(mResources.getDimensionPixelSize(R.dimen.shelf_and_lock_icon_overlap)).thenReturn(5);
- // Available space (100 - 10 - 15 = 75)
+ // Available space (100 - 0 - 15 = 85)
when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(100);
- when(mNotificationStackScrollLayoutController.getTopPadding()).thenReturn(10);
+ when(mNotificationStackScrollLayoutController.getTop()).thenReturn(0);
mNotificationPanelViewController.updateResources();
assertThat(mNotificationPanelViewController.getSpaceForLockscreenNotifications())
- .isEqualTo(75);
+ .isEqualTo(85);
}
@Test
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 ddccd83..c402d2e 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
@@ -26,10 +26,12 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.IActivityManager;
@@ -103,6 +105,7 @@
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
+ verify(mWindowManager).addView(eq(mNotificationShadeWindowView), any());
}
@Test
@@ -174,6 +177,14 @@
}
@Test
+ public void setScrimsVisibility_earlyReturn() {
+ clearInvocations(mWindowManager);
+ mNotificationShadeWindowController.setScrimsVisibility(ScrimController.TRANSPARENT);
+ // Abort early if value didn't change
+ verify(mWindowManager, never()).updateViewLayout(any(), mLayoutParameters.capture());
+ }
+
+ @Test
public void attach_animatingKeyguardAndSurface_wallpaperVisible() {
clearInvocations(mWindowManager);
when(mKeyguardViewMediator.isShowingAndNotOccluded()).thenReturn(true);
@@ -221,6 +232,8 @@
public void setPanelExpanded_notFocusable_altFocusable_whenPanelIsOpen() {
mNotificationShadeWindowController.setPanelExpanded(true);
clearInvocations(mWindowManager);
+ mNotificationShadeWindowController.setPanelExpanded(true);
+ verifyNoMoreInteractions(mWindowManager);
mNotificationShadeWindowController.setNotificationShadeFocusable(true);
verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
@@ -287,6 +300,8 @@
public void batchApplyWindowLayoutParams_doesNotDispatchEvents() {
mNotificationShadeWindowController.setForceDozeBrightness(true);
verify(mWindowManager).updateViewLayout(any(), any());
+ mNotificationShadeWindowController.setForceDozeBrightness(true);
+ verifyNoMoreInteractions(mWindowManager);
clearInvocations(mWindowManager);
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
@@ -295,4 +310,17 @@
});
verify(mWindowManager).updateViewLayout(any(), any());
}
+
+ @Test
+ public void bouncerShowing_OrientationNoSensor() {
+ mNotificationShadeWindowController.setKeyguardShowing(true);
+ mNotificationShadeWindowController.setKeyguardOccluded(true);
+ mNotificationShadeWindowController.setBouncerShowing(true);
+ when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
+ mNotificationShadeWindowController.onConfigChanged(new Configuration());
+
+ verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), mLayoutParameters.capture());
+ assertThat(mLayoutParameters.getValue().screenOrientation)
+ .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index 0936b77..0112797 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -117,11 +117,18 @@
val keyguardSpy = spy(keyguardView)
Mockito.`when`(keyguardSpy.animate()).thenReturn(animator)
val listener = ArgumentCaptor.forClass(Animator.AnimatorListener::class.java)
+ val endAction = ArgumentCaptor.forClass(Runnable::class.java)
controller.animateInKeyguard(keyguardSpy, Runnable {})
Mockito.verify(animator).setListener(listener.capture())
- // Verify that the listener is cleared when it ends
- listener.value.onAnimationEnd(null)
+ Mockito.verify(animator).withEndAction(endAction.capture())
+
+ // Verify that the listener is cleared if we cancel it.
+ listener.value.onAnimationCancel(null)
Mockito.verify(animator).setListener(null)
+
+ // Verify that the listener is also cleared if the end action is triggered.
+ endAction.value.run()
+ verify(animator, times(2)).setListener(null)
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
index e9d16a6..64a93cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -53,7 +53,6 @@
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.never
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.ArgumentMatchers.anyInt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
index 14e0878..9c7dc6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -365,46 +365,4 @@
// No new callbacks
verify(callback).onLocationSettingsChanged(anyBoolean());
}
-
- @Test
- public void testExperimentFlipsSystemFlag() throws Exception {
- mSecureSettings.putInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0);
- mDeviceConfigProxy.setProperty(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SMALL_ENABLED,
- "true",
- true);
- // Show system experiment not running
- mDeviceConfigProxy.setProperty(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
- "false",
- false);
- mTestableLooper.processAllMessages();
-
- // Flip experiment on
- mDeviceConfigProxy.setProperty(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
- "true",
- true);
- mTestableLooper.processAllMessages();
-
- // Verify settings were flipped
- assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS))
- .isEqualTo(1);
- assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED))
- .isEqualTo(1);
-
- // Flip experiment off
- mDeviceConfigProxy.setProperty(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM,
- "false",
- false);
- mTestableLooper.processAllMessages();
-
- assertThat(mSecureSettings.getInt(Settings.Secure.LOCATION_INDICATOR_EXPERIMENT_STARTED))
- .isEqualTo(0);
- }
}
\ No newline at end of file
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 c625dc7..3dfc94b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -729,18 +729,6 @@
mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM,
USER_SYSTEM);
- reset(mResources);
- when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
- .thenReturn(mThemeOverlayController.mColorScheme.getAccent1().get(6));
- when(mResources.getColor(eq(android.R.color.system_accent2_500), any()))
- .thenReturn(mThemeOverlayController.mColorScheme.getAccent2().get(6));
- when(mResources.getColor(eq(android.R.color.system_accent3_500), any()))
- .thenReturn(mThemeOverlayController.mColorScheme.getAccent3().get(6));
- when(mResources.getColor(eq(android.R.color.system_neutral1_500), any()))
- .thenReturn(mThemeOverlayController.mColorScheme.getNeutral1().get(6));
- when(mResources.getColor(eq(android.R.color.system_neutral2_500), any()))
- .thenReturn(mThemeOverlayController.mColorScheme.getNeutral2().get(6));
-
// Defers event because we already have initial colors.
verify(mThemeOverlayApplier, never())
.applyCurrentUserOverlays(any(), any(), anyInt(), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
index aaea4ec..95b62a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
@@ -49,6 +49,11 @@
}
@Override
+ public boolean isBouncerShowing() {
+ return false;
+ }
+
+ @Override
public boolean canDismissLockScreen() {
return false;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 193879e..238a4d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -57,6 +57,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -70,6 +71,8 @@
import android.service.notification.ZenModeConfig;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.Pair;
+import android.util.SparseArray;
import android.view.View;
import android.view.WindowManager;
@@ -147,6 +150,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.HashMap;
import java.util.List;
import java.util.Optional;
@@ -1010,7 +1014,7 @@
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
// Should notify delegate that shade state changed
- verify(mBubbleController).onBubbleNotificationSuppressionChanged(
+ verify(mBubbleController).onBubbleMetadataFlagChanged(
mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
}
@@ -1027,7 +1031,7 @@
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
// Should notify delegate that shade state changed
- verify(mBubbleController).onBubbleNotificationSuppressionChanged(
+ verify(mBubbleController).onBubbleMetadataFlagChanged(
mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
}
@@ -1447,6 +1451,69 @@
assertThat(stackView.getVisibility()).isEqualTo(View.VISIBLE);
}
+ @Test
+ public void testSetShouldAutoExpand_notifiesFlagChanged() {
+ mEntryListener.onPendingEntryAdded(mRow);
+
+ assertTrue(mBubbleController.hasBubbles());
+ Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey());
+ assertThat(b.shouldAutoExpand()).isFalse();
+
+ // Set it to the same thing
+ b.setShouldAutoExpand(false);
+
+ // Verify it doesn't notify
+ verify(mBubbleController, never()).onBubbleMetadataFlagChanged(any());
+
+ // Set it to something different
+ b.setShouldAutoExpand(true);
+ verify(mBubbleController).onBubbleMetadataFlagChanged(b);
+ }
+
+ @Test
+ public void testUpdateBubble_skipsDndSuppressListNotifs() {
+ mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+ mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
+ mRow.shouldSuppressPeek());
+ mBubbleEntry.getBubbleMetadata().setFlags(
+ Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE);
+
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ Bubble b = mBubbleData.getPendingBubbleWithKey(mBubbleEntry.getKey());
+ assertThat(b.shouldAutoExpand()).isFalse();
+ assertThat(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey())).isNull();
+ }
+
+ @Test
+ public void testOnRankingUpdate_DndSuppressListNotif() {
+ // It's in the stack
+ mBubbleController.updateBubble(mBubbleEntry);
+ assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isTrue();
+
+ // Set current user profile
+ SparseArray<UserInfo> userInfos = new SparseArray<>();
+ userInfos.put(mBubbleEntry.getStatusBarNotification().getUser().getIdentifier(),
+ mock(UserInfo.class));
+ mBubbleController.onCurrentProfilesChanged(userInfos);
+
+ // Send ranking update that the notif is suppressed from the list.
+ HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey = new HashMap<>();
+ mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+ mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
+ mRow.shouldSuppressPeek());
+ Pair<BubbleEntry, Boolean> pair = new Pair(mBubbleEntry, true);
+ entryDataByKey.put(mBubbleEntry.getKey(), pair);
+
+ NotificationListenerService.RankingMap rankingMap =
+ mock(NotificationListenerService.RankingMap.class);
+ when(rankingMap.getOrderedKeys()).thenReturn(new String[] { mBubbleEntry.getKey() });
+ mBubbleController.onRankingUpdated(rankingMap, entryDataByKey);
+
+ // Should no longer be in the stack
+ assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isFalse();
+ }
+
/** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index 02d8691..dff89e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -50,6 +50,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherApps;
+import android.content.pm.UserInfo;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
@@ -59,6 +60,8 @@
import android.service.notification.ZenModeConfig;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.Pair;
+import android.util.SparseArray;
import android.view.View;
import android.view.WindowManager;
@@ -128,6 +131,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.HashMap;
import java.util.List;
import java.util.Optional;
@@ -880,7 +884,7 @@
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
// Should notify delegate that shade state changed
- verify(mBubbleController).onBubbleNotificationSuppressionChanged(
+ verify(mBubbleController).onBubbleMetadataFlagChanged(
mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
}
@@ -897,7 +901,7 @@
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
// Should notify delegate that shade state changed
- verify(mBubbleController).onBubbleNotificationSuppressionChanged(
+ verify(mBubbleController).onBubbleMetadataFlagChanged(
mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
}
@@ -1267,6 +1271,69 @@
assertThat(stackView.getVisibility()).isEqualTo(View.VISIBLE);
}
+ @Test
+ public void testSetShouldAutoExpand_notifiesFlagChanged() {
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ assertTrue(mBubbleController.hasBubbles());
+ Bubble b = mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey());
+ assertThat(b.shouldAutoExpand()).isFalse();
+
+ // Set it to the same thing
+ b.setShouldAutoExpand(false);
+
+ // Verify it doesn't notify
+ verify(mBubbleController, never()).onBubbleMetadataFlagChanged(any());
+
+ // Set it to something different
+ b.setShouldAutoExpand(true);
+ verify(mBubbleController).onBubbleMetadataFlagChanged(b);
+ }
+
+ @Test
+ public void testUpdateBubble_skipsDndSuppressListNotifs() {
+ mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+ mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
+ mRow.shouldSuppressPeek());
+ mBubbleEntry.getBubbleMetadata().setFlags(
+ Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE);
+
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ Bubble b = mBubbleData.getPendingBubbleWithKey(mBubbleEntry.getKey());
+ assertThat(b.shouldAutoExpand()).isFalse();
+ assertThat(mBubbleData.getBubbleInStackWithKey(mBubbleEntry.getKey())).isNull();
+ }
+
+ @Test
+ public void testOnRankingUpdate_DndSuppressListNotif() {
+ // It's in the stack
+ mBubbleController.updateBubble(mBubbleEntry);
+ assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isTrue();
+
+ // Set current user profile
+ SparseArray<UserInfo> userInfos = new SparseArray<>();
+ userInfos.put(mBubbleEntry.getStatusBarNotification().getUser().getIdentifier(),
+ mock(UserInfo.class));
+ mBubbleController.onCurrentProfilesChanged(userInfos);
+
+ // Send ranking update that the notif is suppressed from the list.
+ HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey = new HashMap<>();
+ mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+ mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
+ mRow.shouldSuppressPeek());
+ Pair<BubbleEntry, Boolean> pair = new Pair(mBubbleEntry, true);
+ entryDataByKey.put(mBubbleEntry.getKey(), pair);
+
+ NotificationListenerService.RankingMap rankingMap =
+ mock(NotificationListenerService.RankingMap.class);
+ when(rankingMap.getOrderedKeys()).thenReturn(new String[] { mBubbleEntry.getKey() });
+ mBubbleController.onRankingUpdated(rankingMap, entryDataByKey);
+
+ // Should no longer be in the stack
+ assertThat(mBubbleData.hasBubbleInStackWithKey(mBubbleEntry.getKey())).isFalse();
+ }
+
/**
* Sets the bubble metadata flags for this entry. These flags are normally set by
* NotificationManagerService when the notification is sent, however, these tests do not
diff --git a/packages/VpnDialogs/res/values-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index 81903d2..56d8105 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -32,6 +32,6 @@
<string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"לשינוי של הגדרות ה-VPN"</string>
<string name="configure" msgid="4905518375574791375">"הגדרה"</string>
<string name="disconnect" msgid="971412338304200056">"נתק"</string>
- <string name="open_app" msgid="3717639178595958667">"לאפליקציה"</string>
+ <string name="open_app" msgid="3717639178595958667">"פתיחת האפליקציה"</string>
<string name="dismiss" msgid="6192859333764711227">"סגירה"</string>
</resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 649328d..9b29bae 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -242,6 +242,9 @@
int getCurrentUserIdLocked();
+ Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
+ int windowId);
+
boolean isAccessibilityButtonShown();
/**
@@ -551,8 +554,6 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- final MagnificationSpec spec;
- final float[] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -576,11 +577,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
- getTransformMatrixAndSpecLocked(resolvedWindowId);
- transformMatrix = transformMatrixAndSpec.first;
- spec = transformMatrixAndSpec.second;
}
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
+ final float[] transformMatrix = transformMatrixAndSpec.first;
+ final MagnificationSpec spec = transformMatrixAndSpec.second;
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
@@ -628,8 +629,6 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- final MagnificationSpec spec;
- final float [] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -653,11 +652,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
- getTransformMatrixAndSpecLocked(resolvedWindowId);
- transformMatrix = transformMatrixAndSpec.first;
- spec = transformMatrixAndSpec.second;
}
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
+ final float[] transformMatrix = transformMatrixAndSpec.first;
+ final MagnificationSpec spec = transformMatrixAndSpec.second;
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
@@ -706,8 +705,6 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- final MagnificationSpec spec;
- final float[] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -731,11 +728,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
- getTransformMatrixAndSpecLocked(resolvedWindowId);
- transformMatrix = transformMatrixAndSpec.first;
- spec = transformMatrixAndSpec.second;
}
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
+ final float[] transformMatrix = transformMatrixAndSpec.first;
+ final MagnificationSpec spec = transformMatrixAndSpec.second;
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
@@ -786,8 +783,6 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- final MagnificationSpec spec;
- final float[] transformMatrix;
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -811,11 +806,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
- getTransformMatrixAndSpecLocked(resolvedWindowId);
- transformMatrix = transformMatrixAndSpec.first;
- spec = transformMatrixAndSpec.second;
}
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
+ final float[] transformMatrix = transformMatrixAndSpec.first;
+ final MagnificationSpec spec = transformMatrixAndSpec.second;
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
@@ -865,8 +860,6 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- final MagnificationSpec spec;
- final float[] transformMatrix;
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -889,12 +882,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
-
- final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
- getTransformMatrixAndSpecLocked(resolvedWindowId);
- transformMatrix = transformMatrixAndSpec.first;
- spec = transformMatrixAndSpec.second;
}
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
+ final float[] transformMatrix = transformMatrixAndSpec.first;
+ final MagnificationSpec spec = transformMatrixAndSpec.second;
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
@@ -1672,21 +1664,10 @@
mInvocationHandler.startInputLocked(connection, editorInfo, restarting);
}
-
-
@Nullable
- Pair<float[], MagnificationSpec> getTransformMatrixAndSpecLocked(int resolvedWindowId) {
- final WindowInfo windowInfo =
- mA11yWindowManager.findWindowInfoByIdLocked(resolvedWindowId);
- if (windowInfo == null) {
- Slog.w(LOG_TAG, "getTransformMatrixAndSpec, windowInfo is null window id = "
- + resolvedWindowId);
- return new Pair<>(null, null);
- }
-
- final MagnificationSpec spec = new MagnificationSpec();
- spec.setTo(windowInfo.mMagnificationSpec);
- return new Pair<>(windowInfo.mTransformMatrix, spec);
+ private Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
+ int resolvedWindowId) {
+ return mSystemSupport.getWindowTransformationMatrixAndMagnificationSpec(resolvedWindowId);
}
/**
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index cbeb01a..99c8495 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -68,6 +68,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
@@ -99,6 +100,7 @@
import android.text.TextUtils.SimpleStringSplitter;
import android.util.ArraySet;
import android.util.IntArray;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -187,6 +189,13 @@
// their capabilities are ready.
private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000;
+
+ // This postpones state changes events when a window doesn't exist with the expectation that
+ // a race condition will resolve. It is determined by observing elapsed time of the
+ // corresponding window added.
+ //TODO(b/230810909) : Fix it with a better idea.
+ private static final int POSTPONE_WINDOW_STATE_CHANGED_EVENT_TIMEOUT_MILLIS = 500;
+
private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
"registerUiTestAutomationService";
@@ -272,6 +281,9 @@
private final AccessibilityTraceManager mTraceManager;
private final CaptioningManagerImpl mCaptioningManagerImpl;
+ private final List<SendWindowStateChangedEventRunnable> mSendWindowStateChangedEventRunnables =
+ new ArrayList<>();
+
private int mCurrentUserId = UserHandle.USER_SYSTEM;
//TODO: Remove this hack
@@ -448,6 +460,41 @@
}
@Override
+ public Pair<float[], MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
+ int windowId) {
+ WindowInfo windowInfo;
+ synchronized (mLock) {
+ windowInfo = mA11yWindowManager.findWindowInfoByIdLocked(windowId);
+ }
+ if (windowInfo != null) {
+ final MagnificationSpec spec = new MagnificationSpec();
+ spec.setTo(windowInfo.mMagnificationSpec);
+ return new Pair<>(windowInfo.mTransformMatrix, spec);
+ } else {
+ // If the framework doesn't track windows, we fall back to get the pair of
+ // transformation matrix and MagnificationSpe from the WindowManagerService's
+ // WindowState.
+ IBinder token;
+ synchronized (mLock) {
+ token = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(mCurrentUserId,
+ windowId);
+ }
+ Pair<Matrix, MagnificationSpec> pair =
+ mWindowManagerService.getWindowTransformationMatrixAndMagnificationSpec(token);
+ final float[] outTransformationMatrix = new float[9];
+ final Matrix tmpMatrix = pair.first;
+ final MagnificationSpec spec = pair.second;
+ if (!spec.isNop()) {
+ tmpMatrix.postScale(spec.scale, spec.scale);
+ tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
+ }
+ tmpMatrix.getValues(outTransformationMatrix);
+
+ return new Pair<>(outTransformationMatrix, pair.second);
+ }
+ }
+
+ @Override
public void onServiceInfoChangedLocked(AccessibilityUserState userState) {
mSecurityPolicy.onBoundServicesChangedLocked(userState.mUserId,
userState.mBoundServices);
@@ -930,11 +977,15 @@
final WindowManagerInternal wm = LocalServices.getService(
WindowManagerInternal.class);
wm.computeWindowsForAccessibility(displayId);
+ // The App side sends a event to notify that the window visible or focused,
+ // but the window information in framework is not updated yet, so we postpone it.
+ if (postponeWindowStateEvent(event)) {
+ return;
+ }
}
+
synchronized (mLock) {
- notifyAccessibilityServicesDelayedLocked(event, false);
- notifyAccessibilityServicesDelayedLocked(event, true);
- mUiAutomationManager.sendAccessibilityEventLocked(event);
+ dispatchAccessibilityEventLocked(event);
}
}
@@ -943,6 +994,12 @@
}
}
+ private void dispatchAccessibilityEventLocked(AccessibilityEvent event) {
+ notifyAccessibilityServicesDelayedLocked(event, false);
+ notifyAccessibilityServicesDelayedLocked(event, true);
+ mUiAutomationManager.sendAccessibilityEventLocked(event);
+ }
+
private void sendAccessibilityEventToInputFilter(AccessibilityEvent event) {
synchronized (mLock) {
if (mHasInputFilter && mInputFilter != null) {
@@ -3339,6 +3396,11 @@
@Override
public void sendAccessibilityEventForCurrentUserLocked(AccessibilityEvent event) {
+ if (event.getWindowChanges() == AccessibilityEvent.WINDOWS_CHANGE_ADDED) {
+ // We need to ensure the window is available before sending pending
+ // window_state_changed events.
+ sendPendingWindowStateChangedEventsForAvailableWindowLocked(event.getWindowId());
+ }
sendAccessibilityEventLocked(event, mCurrentUserId);
}
@@ -3725,12 +3787,12 @@
boundsInScreenBeforeMagnification.centerY());
// Invert magnification if needed.
- final WindowInfo windowInfo = mA11yWindowManager.findWindowInfoByIdLocked(
- focus.getWindowId());
+ final Pair<float[], MagnificationSpec> pair =
+ getWindowTransformationMatrixAndMagnificationSpec(focus.getWindowId());
MagnificationSpec spec = null;
- if (windowInfo != null) {
+ if (pair != null && pair.second != null) {
spec = new MagnificationSpec();
- spec.setTo(windowInfo.mMagnificationSpec);
+ spec.setTo(pair.second);
}
if (spec != null && !spec.isNop()) {
@@ -4505,4 +4567,67 @@
}
}
}
+
+ private final class SendWindowStateChangedEventRunnable implements Runnable {
+
+ private final AccessibilityEvent mPendingEvent;
+ private final int mWindowId;
+
+ SendWindowStateChangedEventRunnable(@NonNull AccessibilityEvent event) {
+ mPendingEvent = event;
+ mWindowId = event.getWindowId();
+ }
+
+ @Override
+ public void run() {
+ synchronized (mLock) {
+ Slog.w(LOG_TAG, " wait for adding window timeout: " + mWindowId);
+ sendPendingEventLocked();
+ }
+ }
+
+ private void sendPendingEventLocked() {
+ mSendWindowStateChangedEventRunnables.remove(this);
+ dispatchAccessibilityEventLocked(mPendingEvent);
+ }
+
+ private int getWindowId() {
+ return mWindowId;
+ }
+ }
+
+ void sendPendingWindowStateChangedEventsForAvailableWindowLocked(int windowId) {
+ final int eventSize = mSendWindowStateChangedEventRunnables.size();
+ for (int i = eventSize - 1; i >= 0; i--) {
+ final SendWindowStateChangedEventRunnable runnable =
+ mSendWindowStateChangedEventRunnables.get(i);
+ if (runnable.getWindowId() == windowId) {
+ mMainHandler.removeCallbacks(runnable);
+ runnable.sendPendingEventLocked();
+ }
+ }
+ }
+
+ /**
+ * Postpones the {@link AccessibilityEvent} with
+ * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
+ * which doesn't have the corresponding window until the window is added or timeout.
+ *
+ * @return {@code true} if the event is postponed.
+ */
+ private boolean postponeWindowStateEvent(AccessibilityEvent event) {
+ synchronized (mLock) {
+ final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
+ event.getWindowId());
+ if (mA11yWindowManager.findWindowInfoByIdLocked(resolvedWindowId) != null) {
+ return false;
+ }
+ final SendWindowStateChangedEventRunnable pendingRunnable =
+ new SendWindowStateChangedEventRunnable(new AccessibilityEvent(event));
+ mMainHandler.postDelayed(pendingRunnable,
+ POSTPONE_WINDOW_STATE_CHANGED_EVENT_TIMEOUT_MILLIS);
+ mSendWindowStateChangedEventRunnables.add(pendingRunnable);
+ return true;
+ }
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index e30639c..9920cc7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -1661,7 +1661,7 @@
if (traceWMEnabled()) {
logTraceWM("getFocusedWindowToken", "");
}
- final IBinder token = mWindowManagerInternal.getFocusedWindowToken();
+ final IBinder token = mWindowManagerInternal.getFocusedWindowTokenFromWindowStates();
synchronized (mLock) {
return findWindowIdLocked(userId, token);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index f18d13d..6d3620f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1559,9 +1559,18 @@
Slog.e(TAG, "Error sending input show up notification", e);
}
}
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void requestFallbackFromFillDialog() {
+ setFillDialogDisabled();
synchronized (mLock) {
- // stop to show fill dialog
- mSessionFlags.mFillDialogDisabled = true;
+ if (mCurrentViewId == null) {
+ return;
+ }
+ final ViewState currentView = mViewStates.get(mCurrentViewId);
+ currentView.maybeCallOnFillReady(mFlags);
}
}
@@ -3208,16 +3217,24 @@
return;
}
- if (requestShowFillDialog(response, filledId, filterText, flags)) {
- synchronized (mLock) {
- final ViewState currentView = mViewStates.get(mCurrentViewId);
- currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
- mService.logDatasetShown(id, mClientState, UI_TYPE_DIALOG);
+ final AutofillId[] ids = response.getFillDialogTriggerIds();
+ if (ids != null && ArrayUtils.contains(ids, filledId)) {
+ if (requestShowFillDialog(response, filledId, filterText, flags)) {
+ synchronized (mLock) {
+ final ViewState currentView = mViewStates.get(mCurrentViewId);
+ currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
+ mService.logDatasetShown(id, mClientState, UI_TYPE_DIALOG);
+ }
+ // Just show fill dialog once, so disabled after shown.
+ // Note: Cannot disable before requestShowFillDialog() because the method
+ // need to check whether fill dialog enabled.
+ setFillDialogDisabled();
+ return;
+ } else {
+ setFillDialogDisabled();
}
- return;
- }
- setFillDialogDisabled();
+ }
if (response.supportsInlineSuggestions()) {
synchronized (mLock) {
@@ -3324,15 +3341,11 @@
return false;
}
- final AutofillId[] ids = response.getFillDialogTriggerIds();
- if (ids == null || !ArrayUtils.contains(ids, filledId)) {
- return false;
- }
-
final Drawable serviceIcon = getServiceIcon();
getUiForShowing().showFillDialog(filledId, response, filterText,
- mService.getServicePackageName(), mComponentName, serviceIcon, this);
+ mService.getServicePackageName(), mComponentName, serviceIcon, this,
+ id, mCompatMode);
return true;
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 57768ef..3ab873d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -97,6 +97,7 @@
void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent);
void cancelSession();
void requestShowSoftInput(AutofillId id);
+ void requestFallbackFromFillDialog();
}
public AutoFillUI(@NonNull Context context) {
@@ -388,13 +389,19 @@
public void showFillDialog(@NonNull AutofillId focusedId, @NonNull FillResponse response,
@Nullable String filterText, @Nullable String servicePackageName,
@NonNull ComponentName componentName, @Nullable Drawable serviceIcon,
- @NonNull AutoFillUiCallback callback) {
+ @NonNull AutoFillUiCallback callback, int sessionId, boolean compatMode) {
if (sVerbose) {
Slog.v(TAG, "showFillDialog for "
+ componentName.toShortString() + ": " + response);
}
- // TODO: enable LogMaker
+ final LogMaker log = Helper
+ .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, componentName, servicePackageName,
+ sessionId, compatMode)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FILTERTEXT_LEN,
+ filterText == null ? 0 : filterText.length())
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
+ response.getDatasets() == null ? 0 : response.getDatasets().size());
mHandler.post(() -> {
if (callback != mCallback) {
@@ -406,6 +413,7 @@
mUiModeMgr.isNightMode(), new DialogFillUi.UiCallback() {
@Override
public void onResponsePicked(FillResponse response) {
+ log(MetricsEvent.TYPE_DETAIL);
hideFillDialogUiThread(callback);
if (mCallback != null) {
mCallback.authenticate(response.getRequestId(),
@@ -417,6 +425,7 @@
@Override
public void onDatasetPicked(Dataset dataset) {
+ log(MetricsEvent.TYPE_ACTION);
hideFillDialogUiThread(callback);
if (mCallback != null) {
final int datasetIndex = response.getDatasets().indexOf(dataset);
@@ -426,15 +435,29 @@
}
@Override
- public void onCanceled() {
+ public void onDismissed() {
+ log(MetricsEvent.TYPE_DISMISS);
hideFillDialogUiThread(callback);
callback.requestShowSoftInput(focusedId);
}
@Override
+ public void onCanceled() {
+ log(MetricsEvent.TYPE_CLOSE);
+ hideFillDialogUiThread(callback);
+ callback.requestShowSoftInput(focusedId);
+ callback.requestFallbackFromFillDialog();
+ }
+
+ @Override
public void startIntentSender(IntentSender intentSender) {
mCallback.startIntentSenderAndFinishSession(intentSender);
}
+
+ private void log(int type) {
+ log.setType(type);
+ mMetricsLogger.write(log);
+ }
});
});
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
index f9f5289..5a1a1ae 100644
--- a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
@@ -81,6 +81,7 @@
interface UiCallback {
void onResponsePicked(@NonNull FillResponse response);
void onDatasetPicked(@NonNull Dataset dataset);
+ void onDismissed();
void onCanceled();
void startIntentSender(IntentSender intentSender);
}
@@ -144,6 +145,7 @@
mDialog = new Dialog(mContext, mThemeId);
mDialog.setContentView(decor);
setDialogParamsAsBottomSheet();
+ mDialog.setOnCancelListener((d) -> mCallback.onCanceled());
show();
}
@@ -220,7 +222,7 @@
final TextView noButton = decor.findViewById(R.id.autofill_dialog_no);
// set "No thinks" by default
noButton.setText(R.string.autofill_save_no);
- noButton.setOnClickListener((v) -> mCallback.onCanceled());
+ noButton.setOnClickListener((v) -> mCallback.onDismissed());
}
private void setContinueButton(View decor, View.OnClickListener listener) {
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index b4c107c..2a22cac 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -62,7 +62,6 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.UserInfo;
@@ -81,7 +80,6 @@
import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManager;
-import android.text.BidiFormatter;
import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.Log;
@@ -294,6 +292,15 @@
private boolean onCompanionApplicationBindingDiedInternal(
@UserIdInt int userId, @NonNull String packageName) {
+ // Update the current connected devices sets when binderDied, so that application is able
+ // to call notifyDeviceAppeared after re-launch the application.
+ for (AssociationInfo ai :
+ mAssociationStore.getAssociationsForPackage(userId, packageName)) {
+ int id = ai.getId();
+ Slog.i(TAG, "Removing association id: " + id + " for package: "
+ + packageName + " due to binderDied.");
+ mDevicePresenceMonitor.removeDeviceFromMonitoring(id);
+ }
// TODO(b/218613015): implement.
return false;
}
@@ -529,20 +536,12 @@
String callingPackage = component.getPackageName();
checkCanCallNotificationApi(callingPackage);
// TODO: check userId.
- String packageTitle = BidiFormatter.getInstance().unicodeWrap(
- getPackageInfo(getContext(), userId, callingPackage)
- .applicationInfo
- .loadSafeLabel(getContext().getPackageManager(),
- PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
- PackageItemInfo.SAFE_LABEL_FLAG_TRIM
- | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE)
- .toString());
final long identity = Binder.clearCallingIdentity();
try {
return PendingIntent.getActivityAsUser(getContext(),
0 /* request code */,
NotificationAccessConfirmationActivityContract.launcherIntent(
- getContext(), userId, component, packageTitle),
+ getContext(), userId, component),
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_CANCEL_CURRENT,
null /* options */,
@@ -723,9 +722,12 @@
String[] args, ShellCallback callback, ResultReceiver resultReceiver)
throws RemoteException {
enforceCallerCanManageCompanionDevice(getContext(), "onShellCommand");
- new CompanionDeviceShellCommand(
- CompanionDeviceManagerService.this, mAssociationStore)
- .exec(this, in, out, err, args, callback, resultReceiver);
+
+ final CompanionDeviceShellCommand cmd = new CompanionDeviceShellCommand(
+ CompanionDeviceManagerService.this,
+ mAssociationStore,
+ mDevicePresenceMonitor);
+ cmd.exec(this, in, out, err, args, callback, resultReceiver);
}
@Override
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
index fd13085..6a19a42 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
@@ -21,6 +21,8 @@
import android.util.Log;
import android.util.Slog;
+import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
+
import java.io.PrintWriter;
import java.util.List;
@@ -29,20 +31,24 @@
private final CompanionDeviceManagerService mService;
private final AssociationStore mAssociationStore;
+ private final CompanionDevicePresenceMonitor mDevicePresenceMonitor;
CompanionDeviceShellCommand(CompanionDeviceManagerService service,
- AssociationStore associationStore) {
+ AssociationStore associationStore,
+ CompanionDevicePresenceMonitor devicePresenceMonitor) {
mService = service;
mAssociationStore = associationStore;
+ mDevicePresenceMonitor = devicePresenceMonitor;
}
@Override
public int onCommand(String cmd) {
final PrintWriter out = getOutPrintWriter();
+ final int associationId;
try {
switch (cmd) {
case "list": {
- final int userId = getNextArgInt();
+ final int userId = getNextIntArgRequired();
final List<AssociationInfo> associationsForUser =
mAssociationStore.getAssociationsForUser(userId);
for (AssociationInfo association : associationsForUser) {
@@ -55,7 +61,7 @@
break;
case "associate": {
- int userId = getNextArgInt();
+ int userId = getNextIntArgRequired();
String packageName = getNextArgRequired();
String address = getNextArgRequired();
mService.legacyCreateAssociation(userId, address, packageName, null);
@@ -63,7 +69,7 @@
break;
case "disassociate": {
- final int userId = getNextArgInt();
+ final int userId = getNextIntArgRequired();
final String packageName = getNextArgRequired();
final String address = getNextArgRequired();
final AssociationInfo association =
@@ -80,6 +86,16 @@
}
break;
+ case "simulate-device-appeared":
+ associationId = getNextIntArgRequired();
+ mDevicePresenceMonitor.simulateDeviceAppeared(associationId);
+ break;
+
+ case "simulate-device-disappeared":
+ associationId = getNextIntArgRequired();
+ mDevicePresenceMonitor.simulateDeviceDisappeared(associationId);
+ break;
+
default:
return handleDefaultCommands(cmd);
}
@@ -91,10 +107,6 @@
}
}
- private int getNextArgInt() {
- return Integer.parseInt(getNextArgRequired());
- }
-
@Override
public void onHelp() {
PrintWriter pw = getOutPrintWriter();
@@ -108,7 +120,31 @@
pw.println(" disassociate USER_ID PACKAGE MAC_ADDRESS");
pw.println(" Remove an existing Association.");
pw.println(" clear-association-memory-cache");
- pw.println(" Clear the in-memory association cache and reload all association "
- + "information from persistent storage. USE FOR DEBUGGING PURPOSES ONLY.");
+ pw.println(" Clear the in-memory association cache and reload all association ");
+ pw.println(" information from persistent storage. USE FOR DEBUGGING PURPOSES ONLY.");
+ pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
+
+ pw.println(" simulate-device-appeared ASSOCIATION_ID");
+ pw.println(" Make CDM act as if the given companion device has appeared.");
+ pw.println(" I.e. bind the associated companion application's");
+ pw.println(" CompanionDeviceService(s) and trigger onDeviceAppeared() callback.");
+ pw.println(" The CDM will consider the devices as present for 60 seconds and then");
+ pw.println(" will act as if device disappeared, unless 'simulate-device-disappeared'");
+ pw.println(" or 'simulate-device-appeared' is called again before 60 seconds run out"
+ + ".");
+ pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
+
+ pw.println(" simulate-device-disappeared ASSOCIATION_ID");
+ pw.println(" Make CDM act as if the given companion device has disappeared.");
+ pw.println(" I.e. unbind the associated companion application's");
+ pw.println(" CompanionDeviceService(s) and trigger onDeviceDisappeared() callback.");
+ pw.println(" NOTE: This will only have effect if 'simulate-device-appeared' was");
+ pw.println(" invoked for the same device (same ASSOCIATION_ID) no longer than");
+ pw.println(" 60 seconds ago.");
+ pw.println(" USE FOR DEBUGGING AND/OR TESTING PURPOSES ONLY.");
+ }
+
+ private int getNextIntArgRequired() {
+ return Integer.parseInt(getNextArgRequired());
}
}
diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
index 6371b25..37e8369 100644
--- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
+++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java
@@ -16,11 +16,19 @@
package com.android.server.companion.presence;
+import static android.os.Process.ROOT_UID;
+import static android.os.Process.SHELL_UID;
+
import android.annotation.NonNull;
import android.annotation.SuppressLint;
+import android.annotation.TestApi;
import android.bluetooth.BluetoothAdapter;
import android.companion.AssociationInfo;
import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.util.Log;
import com.android.server.companion.AssociationStore;
@@ -72,6 +80,11 @@
private final @NonNull Set<Integer> mNearbyBleDevices = new HashSet<>();
private final @NonNull Set<Integer> mReportedSelfManagedDevices = new HashSet<>();
+ // Tracking "simulated" presence. Used for debugging and testing only.
+ private final @NonNull Set<Integer> mSimulated = new HashSet<>();
+ private final SimulatedDevicePresenceSchedulerHelper mSchedulerHelper =
+ new SimulatedDevicePresenceSchedulerHelper();
+
public CompanionDevicePresenceMonitor(@NonNull AssociationStore associationStore,
@NonNull Callback callback) {
mAssociationStore = associationStore;
@@ -106,7 +119,8 @@
public boolean isDevicePresent(int associationId) {
return mReportedSelfManagedDevices.contains(associationId)
|| mConnectedBtDevices.contains(associationId)
- || mNearbyBleDevices.contains(associationId);
+ || mNearbyBleDevices.contains(associationId)
+ || mSimulated.contains(associationId);
}
/**
@@ -155,6 +169,45 @@
onDeviceGone(mNearbyBleDevices, associationId, /* sourceLoggingTag */ "ble");
}
+ /** FOR DEBUGGING AND/OR TESTING PURPOSES ONLY. */
+ @TestApi
+ public void simulateDeviceAppeared(int associationId) {
+ // IMPORTANT: this API should only be invoked via the
+ // 'companiondevice simulate-device-appeared' Shell command, so the only uid-s allowed to
+ // make this call are SHELL and ROOT.
+ // No other caller (including SYSTEM!) should be allowed.
+ enforceCallerShellOrRoot();
+ // Make sure the association exists.
+ enforceAssociationExists(associationId);
+
+ onDevicePresent(mSimulated, associationId, /* sourceLoggingTag */ "simulated");
+
+ mSchedulerHelper.scheduleOnDeviceGoneCallForSimulatedDevicePresence(associationId);
+ }
+
+ /** FOR DEBUGGING AND/OR TESTING PURPOSES ONLY. */
+ @TestApi
+ public void simulateDeviceDisappeared(int associationId) {
+ // IMPORTANT: this API should only be invoked via the
+ // 'companiondevice simulate-device-appeared' Shell command, so the only uid-s allowed to
+ // make this call are SHELL and ROOT.
+ // No other caller (including SYSTEM!) should be allowed.
+ enforceCallerShellOrRoot();
+ // Make sure the association exists.
+ enforceAssociationExists(associationId);
+
+ mSchedulerHelper.unscheduleOnDeviceGoneCallForSimulatedDevicePresence(associationId);
+
+ onDeviceGone(mSimulated, associationId, /* sourceLoggingTag */ "simulated");
+ }
+
+ private void enforceAssociationExists(int associationId) {
+ if (mAssociationStore.getAssociationById(associationId) == null) {
+ throw new IllegalArgumentException(
+ "Association with id " + associationId + " does not exist.");
+ }
+ }
+
private void onDevicePresent(@NonNull Set<Integer> presentDevicesForSource,
int newDeviceAssociationId, @NonNull String sourceLoggingTag) {
if (DEBUG) {
@@ -206,6 +259,16 @@
}
/**
+ * Remove the current connected devices by associationId.
+ */
+ public void removeDeviceFromMonitoring(int associationId) {
+ mConnectedBtDevices.remove(associationId);
+ mNearbyBleDevices.remove(associationId);
+ mReportedSelfManagedDevices.remove(associationId);
+ mSimulated.remove(associationId);
+ }
+
+ /**
* Implements
* {@link AssociationStore.OnChangeListener#onAssociationRemoved(AssociationInfo)}
*/
@@ -217,12 +280,42 @@
Log.d(TAG, " > association=" + association);
}
- mConnectedBtDevices.remove(id);
- mNearbyBleDevices.remove(id);
- mReportedSelfManagedDevices.remove(id);
+ removeDeviceFromMonitoring(id);
// Do NOT call mCallback.onDeviceDisappeared()!
// CompanionDeviceManagerService will know that the association is removed, and will do
// what's needed.
}
+
+ private static void enforceCallerShellOrRoot() {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid == SHELL_UID || callingUid == ROOT_UID) return;
+
+ throw new SecurityException("Caller is neither Shell nor Root");
+ }
+
+ private class SimulatedDevicePresenceSchedulerHelper extends Handler {
+ SimulatedDevicePresenceSchedulerHelper() {
+ super(Looper.getMainLooper());
+ }
+
+ void scheduleOnDeviceGoneCallForSimulatedDevicePresence(int associationId) {
+ // First, unschedule if it was scheduled previously.
+ if (hasMessages(/* what */ associationId)) {
+ removeMessages(/* what */ associationId);
+ }
+
+ sendEmptyMessageDelayed(/* what */ associationId, 60 * 1000 /* 60 seconds */);
+ }
+
+ void unscheduleOnDeviceGoneCallForSimulatedDevicePresence(int associationId) {
+ removeMessages(/* what */ associationId);
+ }
+
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ final int associationId = msg.what;
+ onDeviceGone(mSimulated, associationId, /* sourceLoggingTag */ "simulated");
+ }
+ }
}
diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java
index 9d4b50b..80182d2 100644
--- a/services/companion/java/com/android/server/companion/virtual/InputController.java
+++ b/services/companion/java/com/android/server/companion/virtual/InputController.java
@@ -22,6 +22,7 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.hardware.display.DisplayManagerInternal;
+import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
import android.hardware.input.VirtualKeyEvent;
@@ -29,11 +30,13 @@
import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualTouchEvent;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.Display;
+import android.view.InputDevice;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -44,7 +47,11 @@
import java.lang.annotation.RetentionPolicy;
import java.util.Iterator;
import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
/** Controls virtual input devices, including device lifecycle and event dispatch. */
class InputController {
@@ -72,20 +79,27 @@
@GuardedBy("mLock")
final Map<IBinder, InputDeviceDescriptor> mInputDeviceDescriptors = new ArrayMap<>();
+ private final Handler mHandler;
private final NativeWrapper mNativeWrapper;
private final DisplayManagerInternal mDisplayManagerInternal;
private final InputManagerInternal mInputManagerInternal;
+ private final DeviceCreationThreadVerifier mThreadVerifier;
- InputController(@NonNull Object lock) {
- this(lock, new NativeWrapper());
+ InputController(@NonNull Object lock, @NonNull Handler handler) {
+ this(lock, new NativeWrapper(), handler,
+ // Verify that virtual devices are not created on the handler thread.
+ () -> !handler.getLooper().isCurrentThread());
}
@VisibleForTesting
- InputController(@NonNull Object lock, @NonNull NativeWrapper nativeWrapper) {
+ InputController(@NonNull Object lock, @NonNull NativeWrapper nativeWrapper,
+ @NonNull Handler handler, @NonNull DeviceCreationThreadVerifier threadVerifier) {
mLock = lock;
+ mHandler = handler;
mNativeWrapper = nativeWrapper;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
+ mThreadVerifier = threadVerifier;
}
void close() {
@@ -108,23 +122,13 @@
@NonNull IBinder deviceToken,
int displayId) {
final String phys = createPhys(PHYS_TYPE_KEYBOARD);
- setUniqueIdAssociation(displayId, phys);
- final int fd = mNativeWrapper.openUinputKeyboard(deviceName, vendorId, productId, phys);
- if (fd < 0) {
- throw new RuntimeException(
- "A native error occurred when creating keyboard: " + -fd);
- }
- final BinderDeathRecipient binderDeathRecipient = new BinderDeathRecipient(deviceToken);
- synchronized (mLock) {
- mInputDeviceDescriptors.put(deviceToken,
- new InputDeviceDescriptor(fd, binderDeathRecipient,
- InputDeviceDescriptor.TYPE_KEYBOARD, displayId, phys));
- }
try {
- deviceToken.linkToDeath(binderDeathRecipient, /* flags= */ 0);
- } catch (RemoteException e) {
- // TODO(b/215608394): remove and close InputDeviceDescriptor
- throw new RuntimeException("Could not create virtual keyboard", e);
+ createDeviceInternal(InputDeviceDescriptor.TYPE_KEYBOARD, deviceName, vendorId,
+ productId, deviceToken, displayId, phys,
+ () -> mNativeWrapper.openUinputKeyboard(deviceName, vendorId, productId, phys));
+ } catch (DeviceCreationException e) {
+ throw new RuntimeException(
+ "Failed to create virtual keyboard device '" + deviceName + "'.", e);
}
}
@@ -134,25 +138,15 @@
@NonNull IBinder deviceToken,
int displayId) {
final String phys = createPhys(PHYS_TYPE_MOUSE);
- setUniqueIdAssociation(displayId, phys);
- final int fd = mNativeWrapper.openUinputMouse(deviceName, vendorId, productId, phys);
- if (fd < 0) {
- throw new RuntimeException(
- "A native error occurred when creating mouse: " + -fd);
- }
- final BinderDeathRecipient binderDeathRecipient = new BinderDeathRecipient(deviceToken);
- synchronized (mLock) {
- mInputDeviceDescriptors.put(deviceToken,
- new InputDeviceDescriptor(fd, binderDeathRecipient,
- InputDeviceDescriptor.TYPE_MOUSE, displayId, phys));
- mInputManagerInternal.setVirtualMousePointerDisplayId(displayId);
- }
try {
- deviceToken.linkToDeath(binderDeathRecipient, /* flags= */ 0);
- } catch (RemoteException e) {
- // TODO(b/215608394): remove and close InputDeviceDescriptor
- throw new RuntimeException("Could not create virtual mouse", e);
+ createDeviceInternal(InputDeviceDescriptor.TYPE_MOUSE, deviceName, vendorId, productId,
+ deviceToken, displayId, phys,
+ () -> mNativeWrapper.openUinputMouse(deviceName, vendorId, productId, phys));
+ } catch (DeviceCreationException e) {
+ throw new RuntimeException(
+ "Failed to create virtual mouse device: '" + deviceName + "'.", e);
}
+ mInputManagerInternal.setVirtualMousePointerDisplayId(displayId);
}
void createTouchscreen(@NonNull String deviceName,
@@ -162,24 +156,14 @@
int displayId,
@NonNull Point screenSize) {
final String phys = createPhys(PHYS_TYPE_TOUCHSCREEN);
- setUniqueIdAssociation(displayId, phys);
- final int fd = mNativeWrapper.openUinputTouchscreen(deviceName, vendorId, productId, phys,
- screenSize.y, screenSize.x);
- if (fd < 0) {
- throw new RuntimeException(
- "A native error occurred when creating touchscreen: " + -fd);
- }
- final BinderDeathRecipient binderDeathRecipient = new BinderDeathRecipient(deviceToken);
- synchronized (mLock) {
- mInputDeviceDescriptors.put(deviceToken,
- new InputDeviceDescriptor(fd, binderDeathRecipient,
- InputDeviceDescriptor.TYPE_TOUCHSCREEN, displayId, phys));
- }
try {
- deviceToken.linkToDeath(binderDeathRecipient, /* flags= */ 0);
- } catch (RemoteException e) {
- // TODO(b/215608394): remove and close InputDeviceDescriptor
- throw new RuntimeException("Could not create virtual touchscreen", e);
+ createDeviceInternal(InputDeviceDescriptor.TYPE_TOUCHSCREEN, deviceName, vendorId,
+ productId, deviceToken, displayId, phys,
+ () -> mNativeWrapper.openUinputTouchscreen(deviceName, vendorId, productId,
+ phys, screenSize.y, screenSize.x));
+ } catch (DeviceCreationException e) {
+ throw new RuntimeException(
+ "Failed to create virtual touchscreen device '" + deviceName + "'.", e);
}
}
@@ -510,4 +494,133 @@
unregisterInputDevice(mDeviceToken);
}
}
+
+ /** A helper class used to wait for an input device to be registered. */
+ private class WaitForDevice implements AutoCloseable {
+ private final CountDownLatch mDeviceAddedLatch = new CountDownLatch(1);
+ private final InputManager.InputDeviceListener mListener;
+
+ WaitForDevice(String deviceName, int vendorId, int productId) {
+ mListener = new InputManager.InputDeviceListener() {
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ final InputDevice device = InputManager.getInstance().getInputDevice(
+ deviceId);
+ Objects.requireNonNull(device, "Newly added input device was null.");
+ if (!device.getName().equals(deviceName)) {
+ return;
+ }
+ final InputDeviceIdentifier id = device.getIdentifier();
+ if (id.getVendorId() != vendorId || id.getProductId() != productId) {
+ return;
+ }
+ mDeviceAddedLatch.countDown();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+
+ }
+ };
+ InputManager.getInstance().registerInputDeviceListener(mListener, mHandler);
+ }
+
+ /** Note: This must not be called from {@link #mHandler}'s thread. */
+ void waitForDeviceCreation() throws DeviceCreationException {
+ try {
+ if (!mDeviceAddedLatch.await(1, TimeUnit.MINUTES)) {
+ throw new DeviceCreationException(
+ "Timed out waiting for virtual device to be created.");
+ }
+ } catch (InterruptedException e) {
+ throw new DeviceCreationException(
+ "Interrupted while waiting for virtual device to be created.", e);
+ }
+ }
+
+ @Override
+ public void close() {
+ InputManager.getInstance().unregisterInputDeviceListener(mListener);
+ }
+ }
+
+ /** An internal exception that is thrown to indicate an error when opening a virtual device. */
+ private static class DeviceCreationException extends Exception {
+ DeviceCreationException(String message) {
+ super(message);
+ }
+ DeviceCreationException(String message, Exception cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * Creates a virtual input device synchronously, and waits for the notification that the device
+ * was added.
+ *
+ * Note: Input device creation is expected to happen on a binder thread, and the calling thread
+ * will be blocked until the input device creation is successful. This should not be called on
+ * the handler's thread.
+ *
+ * @throws DeviceCreationException Throws this exception if anything unexpected happens in the
+ * process of creating the device. This method will take care
+ * to restore the state of the system in the event of any
+ * unexpected behavior.
+ */
+ private void createDeviceInternal(@InputDeviceDescriptor.Type int type, String deviceName,
+ int vendorId, int productId, IBinder deviceToken, int displayId, String phys,
+ Supplier<Integer> deviceOpener)
+ throws DeviceCreationException {
+ if (!mThreadVerifier.isValidThread()) {
+ throw new IllegalStateException(
+ "Virtual device creation should happen on an auxiliary thread (e.g. binder "
+ + "thread) and not from the handler's thread.");
+ }
+
+ final int fd;
+ final BinderDeathRecipient binderDeathRecipient;
+
+ setUniqueIdAssociation(displayId, phys);
+ try (WaitForDevice waiter = new WaitForDevice(deviceName, vendorId, productId)) {
+ fd = deviceOpener.get();
+ if (fd < 0) {
+ throw new DeviceCreationException(
+ "A native error occurred when creating touchscreen: " + -fd);
+ }
+ // The fd is valid from here, so ensure that all failures close the fd after this point.
+ try {
+ waiter.waitForDeviceCreation();
+
+ binderDeathRecipient = new BinderDeathRecipient(deviceToken);
+ try {
+ deviceToken.linkToDeath(binderDeathRecipient, /* flags= */ 0);
+ } catch (RemoteException e) {
+ throw new DeviceCreationException(
+ "Client died before virtual device could be created.", e);
+ }
+ } catch (DeviceCreationException e) {
+ mNativeWrapper.closeUinput(fd);
+ throw e;
+ }
+ } catch (DeviceCreationException e) {
+ InputManager.getInstance().removeUniqueIdAssociation(phys);
+ throw e;
+ }
+
+ synchronized (mLock) {
+ mInputDeviceDescriptors.put(deviceToken,
+ new InputDeviceDescriptor(fd, binderDeathRecipient, type, displayId, phys));
+ }
+ }
+
+ @VisibleForTesting
+ interface DeviceCreationThreadVerifier {
+ /** Returns true if the calling thread is a valid thread for device creation. */
+ boolean isValidThread();
+ }
}
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 de14ef6..9802b97 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -166,7 +166,8 @@
mAppToken = token;
mParams = params;
if (inputController == null) {
- mInputController = new InputController(mVirtualDeviceLock);
+ mInputController = new InputController(
+ mVirtualDeviceLock, context.getMainThreadHandler());
} else {
mInputController = inputController;
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 8f37823..bc40170 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3055,19 +3055,7 @@
return true;
}
- if (packageName == null) {
- return false;
- }
-
- final int packageUid = mPmInternal.getPackageUid(packageName,
- PackageManager.MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callerUid));
-
- if (DEBUG_OBB) {
- Slog.d(TAG, "packageName = " + packageName + ", packageUid = " +
- packageUid + ", callerUid = " + callerUid);
- }
-
- return callerUid == packageUid;
+ return mPmInternal.isSameApp(packageName, callerUid, UserHandle.getUserId(callerUid));
}
@Override
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5cf9090..6fa3bc8 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -6349,8 +6349,8 @@
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
}
if (r.mAllowStartForeground == REASON_DENIED) {
- r.mAllowStartForeground = shouldAllowFgsStartForegroundLocked(allowWhileInUse,
- callingPackage, callingPid, callingUid, intent, r,
+ r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
+ allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
userId);
}
}
@@ -6372,8 +6372,14 @@
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
callingPackage, callingPid, callingUid, null /* serviceRecord */,
false /* allowBackgroundActivityStarts */);
- final @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundLocked(
+ @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundNoBindingCheckLocked(
allowWhileInUse, callingPid, callingUid, callingPackage, null /* targetService */);
+
+ if (allowStartFgs == REASON_DENIED) {
+ if (canBindingClientStartFgsLocked(callingUid) != null) {
+ allowStartFgs = REASON_FGS_BINDING;
+ }
+ }
return allowStartFgs != REASON_DENIED;
}
@@ -6488,33 +6494,19 @@
}
/**
- * Should allow the FGS to start (AKA startForeground()) or not.
- * The check in this method is in addition to check in
- * {@link #shouldAllowFgsWhileInUsePermissionLocked}
- * @param allowWhileInUse the return code from {@link #shouldAllowFgsWhileInUsePermissionLocked}
- * @param callingPackage caller app's package name.
- * @param callingUid caller app's uid.
- * @param intent intent to start/bind service.
- * @param r the service to start.
- * @return {@link ReasonCode}
+ * The uid is not allowed to start FGS, but the uid has a service that is bound
+ * by a clientUid, if the clientUid can start FGS, then the clientUid can propagate its
+ * BG-FGS-start capability down to the callingUid.
+ * @param uid
+ * @return The first binding client's packageName that can start FGS. Return null if no client
+ * can start FGS.
*/
- private @ReasonCode int shouldAllowFgsStartForegroundLocked(
- @ReasonCode int allowWhileInUse, String callingPackage, int callingPid,
- int callingUid, Intent intent, ServiceRecord r, int userId) {
- ActivityManagerService.FgsTempAllowListItem tempAllowListReason =
- r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
- int ret = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPid, callingUid,
- callingPackage, r);
-
+ private String canBindingClientStartFgsLocked(int uid) {
String bindFromPackage = null;
- if (ret == REASON_DENIED) {
- // If the callingUid is not allowed to start FGS, check if the callingUid has any
- // service that is bound by a clientUid, the clientUid can propagate its BG-FGS-start
- // capability down to the callingUid.
- final ArraySet<Integer> checkedClientUids = new ArraySet<>();
- final Pair<Integer, String> isAllowed = mAm.mProcessList.searchEachLruProcessesLOSP(
- false, pr -> {
- if (pr.uid == callingUid) {
+ final ArraySet<Integer> checkedClientUids = new ArraySet<>();
+ final Pair<Integer, String> isAllowed = mAm.mProcessList.searchEachLruProcessesLOSP(
+ false, pr -> {
+ if (pr.uid == uid) {
final ProcessServiceRecord psr = pr.mServices;
final int serviceCount = psr.mServices.size();
for (int svc = 0; svc < serviceCount; svc++) {
@@ -6540,18 +6532,21 @@
final int clientUid = clientPr.uid;
// An UID can bind to itself, do not check on itself again.
// Also skip already checked clientUid.
- if (clientUid == callingUid
+ if (clientUid == uid
|| checkedClientUids.contains(clientUid)) {
continue;
}
final String clientPackageName = cr.clientPackageName;
final @ReasonCode int allowWhileInUse2 =
- shouldAllowFgsWhileInUsePermissionLocked(clientPackageName,
+ shouldAllowFgsWhileInUsePermissionLocked(
+ clientPackageName,
clientPid, clientUid, null /* serviceRecord */,
false /* allowBackgroundActivityStarts */);
final @ReasonCode int allowStartFgs =
- shouldAllowFgsStartForegroundLocked(allowWhileInUse2,
- clientPid, clientUid, clientPackageName, null /* targetService */);
+ shouldAllowFgsStartForegroundNoBindingCheckLocked(
+ allowWhileInUse2,
+ clientPid, clientUid, clientPackageName,
+ null /* targetService */);
if (allowStartFgs != REASON_DENIED) {
return new Pair<>(allowStartFgs, clientPackageName);
} else {
@@ -6564,9 +6559,36 @@
}
return null;
});
- if (isAllowed != null) {
+ if (isAllowed != null) {
+ bindFromPackage = isAllowed.second;
+ }
+ return bindFromPackage;
+ }
+
+ /**
+ * Should allow the FGS to start (AKA startForeground()) or not.
+ * The check in this method is in addition to check in
+ * {@link #shouldAllowFgsWhileInUsePermissionLocked}
+ * @param allowWhileInUse the return code from {@link #shouldAllowFgsWhileInUsePermissionLocked}
+ * @param callingPackage caller app's package name.
+ * @param callingUid caller app's uid.
+ * @param intent intent to start/bind service.
+ * @param r the service to start.
+ * @return {@link ReasonCode}
+ */
+ private @ReasonCode int shouldAllowFgsStartForegroundWithBindingCheckLocked(
+ @ReasonCode int allowWhileInUse, String callingPackage, int callingPid,
+ int callingUid, Intent intent, ServiceRecord r, int userId) {
+ ActivityManagerService.FgsTempAllowListItem tempAllowListReason =
+ r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
+ int ret = shouldAllowFgsStartForegroundNoBindingCheckLocked(allowWhileInUse, callingPid,
+ callingUid, callingPackage, r);
+
+ String bindFromPackage = null;
+ if (ret == REASON_DENIED) {
+ bindFromPackage = canBindingClientStartFgsLocked(callingUid);
+ if (bindFromPackage != null) {
ret = REASON_FGS_BINDING;
- bindFromPackage = isAllowed.second;
}
}
@@ -6604,8 +6626,8 @@
return ret;
}
- private @ReasonCode int shouldAllowFgsStartForegroundLocked(@ReasonCode int allowWhileInUse,
- int callingPid, int callingUid, String callingPackage,
+ private @ReasonCode int shouldAllowFgsStartForegroundNoBindingCheckLocked(
+ @ReasonCode int allowWhileInUse, int callingPid, int callingUid, String callingPackage,
@Nullable ServiceRecord targetService) {
int ret = allowWhileInUse;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2ceb00d..dea8cc0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -89,7 +89,6 @@
import static android.os.Process.myPid;
import static android.os.Process.myUid;
import static android.os.Process.readProcFile;
-import static android.os.Process.removeAllProcessGroups;
import static android.os.Process.sendSignal;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;
@@ -2440,8 +2439,6 @@
}
private void start() {
- removeAllProcessGroups();
-
mBatteryStatsService.publish();
mAppOpsService.publish();
mProcessStats.publish();
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 6e28d8f..c09bb2d 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -56,7 +56,6 @@
import android.os.BatteryStatsInternal;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.Build;
import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.SystemClock;
@@ -68,6 +67,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -97,7 +97,7 @@
static final boolean DEBUG_BACKGROUND_BATTERY_TRACKER = false;
static final boolean DEBUG_BACKGROUND_BATTERY_TRACKER_VERBOSE =
- DEBUG_BACKGROUND_BATTERY_TRACKER | Build.IS_DEBUGGABLE;
+ DEBUG_BACKGROUND_BATTERY_TRACKER | false;
// As we don't support realtime per-UID battery usage stats yet, we're polling the stats
// in a regular time basis.
@@ -361,6 +361,7 @@
mUidBatteryUsageInWindow.removeAt(i);
}
}
+ mInjector.getPolicy().onUserRemovedLocked(userId);
}
}
@@ -369,6 +370,7 @@
synchronized (mLock) {
mUidBatteryUsage.delete(uid);
mUidBatteryUsageInWindow.delete(uid);
+ mInjector.getPolicy().onUidRemovedLocked(uid);
}
}
@@ -1209,6 +1211,14 @@
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_window";
/**
+ * The grace period after an interaction event with the app, if the background current
+ * drain goes beyond the threshold within that period, the system won't apply the
+ * restrictions.
+ */
+ static final String KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD =
+ DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "current_drain_interaction_grace_period";
+
+ /**
* Similar to {@link #KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET}, but a higher
* value for the legitimate cases with higher background current drain.
*/
@@ -1311,6 +1321,11 @@
final long mDefaultBgCurrentDrainWindowMs;
/**
+ * Default value to {@link #mBgCurrentDrainInteractionGracePeriodMs}.
+ */
+ final long mDefaultBgCurrentDrainInteractionGracePeriodMs;
+
+ /**
* Default value to the {@link #INDEX_HIGH_CURRENT_DRAIN_THRESHOLD} of
* the {@link #mBgCurrentDrainRestrictedBucketThreshold}.
*/
@@ -1395,6 +1410,11 @@
volatile long mBgCurrentDrainWindowMs;
/**
+ * @see #KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD.
+ */
+ volatile long mBgCurrentDrainInteractionGracePeriodMs;
+
+ /**
* @see #KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION.
*/
volatile long mBgCurrentDrainMediaPlaybackMinDuration;
@@ -1456,6 +1476,12 @@
private final SparseArray<Pair<long[], ImmutableBatteryUsage[]>> mHighBgBatteryPackages =
new SparseArray<>();
+ /**
+ * The timestamp of the last interaction, key is the UID.
+ */
+ @GuardedBy("mLock")
+ private final SparseLongArray mLastInteractionTime = new SparseLongArray();
+
@NonNull
private final Object mLock;
@@ -1479,6 +1505,7 @@
isLowRamDeviceStatic() ? val[1] : val[0];
mDefaultBgCurrentDrainWindowMs = resources.getInteger(
R.integer.config_bg_current_drain_window) * 1_000;
+ mDefaultBgCurrentDrainInteractionGracePeriodMs = mDefaultBgCurrentDrainWindowMs;
val = getFloatArray(resources.obtainTypedArray(
R.array.config_bg_current_drain_high_threshold_to_restricted_bucket));
mDefaultBgCurrentDrainRestrictedBucketHighThreshold =
@@ -1512,6 +1539,8 @@
mBgCurrentDrainBgRestrictedThreshold[1] =
mDefaultBgCurrentDrainBgRestrictedHighThreshold;
mBgCurrentDrainWindowMs = mDefaultBgCurrentDrainWindowMs;
+ mBgCurrentDrainInteractionGracePeriodMs =
+ mDefaultBgCurrentDrainInteractionGracePeriodMs;
mBgCurrentDrainMediaPlaybackMinDuration =
mDefaultBgCurrentDrainMediaPlaybackMinDuration;
mBgCurrentDrainLocationMinDuration = mDefaultBgCurrentDrainLocationMinDuration;
@@ -1543,6 +1572,9 @@
case KEY_BG_CURRENT_DRAIN_WINDOW:
updateCurrentDrainWindow();
break;
+ case KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD:
+ updateCurrentDrainInteractionGracePeriod();
+ break;
case KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION:
updateCurrentDrainMediaPlaybackMinDuration();
break;
@@ -1627,6 +1659,13 @@
mDefaultBgCurrentDrainWindowMs);
}
+ private void updateCurrentDrainInteractionGracePeriod() {
+ mBgCurrentDrainInteractionGracePeriodMs = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD,
+ mDefaultBgCurrentDrainInteractionGracePeriodMs);
+ }
+
private void updateCurrentDrainMediaPlaybackMinDuration() {
mBgCurrentDrainMediaPlaybackMinDuration = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1669,6 +1708,7 @@
super.onSystemReady();
updateCurrentDrainThreshold();
updateCurrentDrainWindow();
+ updateCurrentDrainInteractionGracePeriod();
updateCurrentDrainMediaPlaybackMinDuration();
updateCurrentDrainLocationMinDuration();
updateCurrentDrainEventDurationBasedThresholdEnabled();
@@ -1686,8 +1726,10 @@
synchronized (mLock) {
final Pair<long[], ImmutableBatteryUsage[]> pair = mHighBgBatteryPackages.get(uid);
if (pair != null) {
+ final long lastInteractionTime = mLastInteractionTime.get(uid, 0L);
final long[] ts = pair.first;
- final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] > 0
+ final int restrictedLevel = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET]
+ > (lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs)
&& mTracker.mAppRestrictionController.isAutoRestrictAbusiveAppEnabled()
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
@@ -1778,6 +1820,7 @@
// We're already in the background restricted level, nothing more we could do.
return;
}
+ final long lastInteractionTime = mLastInteractionTime.get(uid, 0L);
final long now = SystemClock.elapsedRealtime();
final int thresholdIndex = getCurrentDrainThresholdIndex(uid, now,
mBgCurrentDrainWindowMs);
@@ -1789,13 +1832,17 @@
long[] ts = null;
ImmutableBatteryUsage[] usages = null;
if (rbPercentage >= rbThreshold) {
- // New findings to us, track it and let the controller know.
- ts = new long[TIME_STAMP_INDEX_LAST];
- ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
- usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST];
- usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
- mHighBgBatteryPackages.put(uid, Pair.create(ts, usages));
- notifyController = excessive = true;
+ if (now > lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs) {
+ // New findings to us, track it and let the controller know.
+ ts = new long[TIME_STAMP_INDEX_LAST];
+ ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
+ usages = new ImmutableBatteryUsage[TIME_STAMP_INDEX_LAST];
+ usages[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
+ mHighBgBatteryPackages.put(uid, Pair.create(ts, usages));
+ // It's beeen long enough since last interaction with this app.
+ notifyController = true;
+ }
+ excessive = true;
}
if (decoupleThresholds && brPercentage >= brThreshold) {
if (ts == null) {
@@ -1813,11 +1860,15 @@
final long[] ts = pair.first;
final long lastRestrictBucketTs = ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET];
if (rbPercentage >= rbThreshold) {
- if (lastRestrictBucketTs == 0) {
- ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
- pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
+ if (now > lastInteractionTime + mBgCurrentDrainInteractionGracePeriodMs) {
+ if (lastRestrictBucketTs == 0) {
+ ts[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = now;
+ pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
+ }
+ // It's been long enough since last interaction with this app.
+ notifyController = true;
}
- notifyController = excessive = true;
+ excessive = true;
} else {
// It's actually back to normal, but we don't untrack it until
// explicit user interactions, because the restriction could be the cause
@@ -1834,7 +1885,7 @@
&& (now > lastRestrictBucketTs + mBgCurrentDrainWindowMs));
if (notifyController) {
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = now;
- pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = usage;
+ pair.second[TIME_STAMP_INDEX_BG_RESTRICTED] = usage;
}
excessive = true;
} else {
@@ -1842,7 +1893,7 @@
// user consent to unrestrict it; or if it's in restricted bucket level,
// resetting this won't lift it from that level.
ts[TIME_STAMP_INDEX_BG_RESTRICTED] = 0;
- pair.second[TIME_STAMP_INDEX_RESTRICTED_BUCKET] = null;
+ pair.second[TIME_STAMP_INDEX_BG_RESTRICTED] = null;
// Now need to notify the controller.
}
}
@@ -1903,6 +1954,7 @@
void onUserInteractionStarted(String packageName, int uid) {
boolean changed = false;
synchronized (mLock) {
+ mLastInteractionTime.put(uid, SystemClock.elapsedRealtime());
final int curLevel = mTracker.mAppRestrictionController.getRestrictionLevel(
uid, packageName);
if (curLevel == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
@@ -1941,9 +1993,30 @@
@VisibleForTesting
void reset() {
mHighBgBatteryPackages.clear();
+ mLastInteractionTime.clear();
mTracker.reset();
}
+ @GuardedBy("mLock")
+ void onUserRemovedLocked(final @UserIdInt int userId) {
+ for (int i = mHighBgBatteryPackages.size() - 1; i >= 0; i--) {
+ if (UserHandle.getUserId(mHighBgBatteryPackages.keyAt(i)) == userId) {
+ mHighBgBatteryPackages.removeAt(i);
+ }
+ }
+ for (int i = mLastInteractionTime.size() - 1; i >= 0; i--) {
+ if (UserHandle.getUserId(mLastInteractionTime.keyAt(i)) == userId) {
+ mLastInteractionTime.removeAt(i);
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
+ void onUidRemovedLocked(final int uid) {
+ mHighBgBatteryPackages.remove(uid);
+ mLastInteractionTime.delete(uid);
+ }
+
@Override
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
@@ -1977,6 +2050,10 @@
pw.print('=');
pw.println(mBgCurrentDrainWindowMs);
pw.print(prefix);
+ pw.print(KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD);
+ pw.print('=');
+ pw.println(mBgCurrentDrainInteractionGracePeriodMs);
+ pw.print(prefix);
pw.print(KEY_BG_CURRENT_DRAIN_MEDIA_PLAYBACK_MIN_DURATION);
pw.print('=');
pw.println(mBgCurrentDrainMediaPlaybackMinDuration);
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index f7abb11..6f5d87b 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -265,6 +265,20 @@
*/
private int[] mDeviceIdleExceptIdleAllowlist = new int[0]; // No lock is needed.
+ /**
+ * The pre-configured system app-ids in the power-save allow list.
+ *
+ * @see #mDeviceIdleAllowlist.
+ */
+ private final ArraySet<Integer> mSystemDeviceIdleAllowlist = new ArraySet<>();
+
+ /**
+ * The pre-configured system app-ids in the power-save allow list, except-idle.
+ *
+ * @see #mDeviceIdleExceptIdleAllowlist.
+ */
+ private final ArraySet<Integer> mSystemDeviceIdleExceptIdleAllowlist = new ArraySet<>();
+
private final Object mLock = new Object();
private final Object mSettingsLock = new Object();
private final Injector mInjector;
@@ -1511,14 +1525,33 @@
}
private void initBgRestrictionExemptioFromSysConfig() {
- mBgRestrictionExemptioFromSysConfig =
- SystemConfig.getInstance().getBgRestrictionExemption();
+ final SystemConfig sysConfig = SystemConfig.getInstance();
+ mBgRestrictionExemptioFromSysConfig = sysConfig.getBgRestrictionExemption();
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
final ArraySet<String> exemptedPkgs = mBgRestrictionExemptioFromSysConfig;
for (int i = exemptedPkgs.size() - 1; i >= 0; i--) {
Slog.i(TAG, "bg-restriction-exemption: " + exemptedPkgs.valueAt(i));
}
}
+ loadAppIdsFromPackageList(sysConfig.getAllowInPowerSaveExceptIdle(),
+ mSystemDeviceIdleExceptIdleAllowlist);
+ loadAppIdsFromPackageList(sysConfig.getAllowInPowerSave(), mSystemDeviceIdleAllowlist);
+ }
+
+ private void loadAppIdsFromPackageList(ArraySet<String> packages, ArraySet<Integer> apps) {
+ final PackageManager pm = mInjector.getPackageManager();
+ for (int i = packages.size() - 1; i >= 0; i--) {
+ final String pkg = packages.valueAt(i);
+ try {
+ final ApplicationInfo ai = pm.getApplicationInfo(pkg,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ if (ai == null) {
+ continue;
+ }
+ apps.add(UserHandle.getAppId(ai.uid));
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
}
private boolean isExemptedFromSysConfig(String packageName) {
@@ -2685,6 +2718,13 @@
|| Arrays.binarySearch(mDeviceIdleExceptIdleAllowlist, appId) >= 0;
}
+ boolean isOnSystemDeviceIdleAllowlist(int uid) {
+ final int appId = UserHandle.getAppId(uid);
+
+ return mSystemDeviceIdleAllowlist.contains(appId)
+ || mSystemDeviceIdleExceptIdleAllowlist.contains(appId);
+ }
+
void setDeviceIdleAllowlist(int[] allAppids, int[] exceptIdleAppids) {
mDeviceIdleAllowlist = allAppids;
mDeviceIdleExceptIdleAllowlist = exceptIdleAppids;
@@ -2703,6 +2743,9 @@
if (UserHandle.isCore(uid)) {
return REASON_SYSTEM_UID;
}
+ if (isOnSystemDeviceIdleAllowlist(uid)) {
+ return REASON_SYSTEM_ALLOW_LISTED;
+ }
if (isOnDeviceIdleAllowlist(uid)) {
return REASON_ALLOWLISTED_PACKAGE;
}
@@ -2748,7 +2791,7 @@
} else if (isExemptedFromSysConfig(pkg)) {
return REASON_SYSTEM_ALLOW_LISTED;
} else if (mConstantsObserver.mBgRestrictionExemptedPackages.contains(pkg)) {
- return REASON_ALLOWLISTED_PACKAGE;
+ return REASON_SYSTEM_ALLOW_LISTED;
} else if (pm.isPackageStateProtected(pkg, userId)) {
return REASON_DPO_PROTECTED_APP;
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index a172018..e49497e 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -479,19 +479,33 @@
@GuardedBy("mProcLock")
void compactAppSome(ProcessRecord app, boolean force) {
app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_SOME);
- if (DEBUG_COMPACTION) {
- Slog.d(TAG_AM, " compactAppSome requested for " + app.processName + " force: " + force);
+ compactApp(app, force, "some");
+ }
+
+ // This method returns true only if requirements are met. Note, that requirements are different
+ // from throttles applied at the time a compaction is trying to be executed in the sense that
+ // these are not subject to change dependent on time or memory as throttles usually do.
+ @GuardedBy("mProcLock")
+ boolean meetsCompactionRequirements(ProcessRecord proc) {
+ if (mAm.mInternal.isPendingTopUid(proc.uid)) {
+ // In case the OOM Adjust has not yet been propagated we see if this is
+ // pending on becoming top app in which case we should not compact.
+ if (DEBUG_COMPACTION) {
+ Slog.d(TAG_AM, "Skip compaction since UID is active for " + proc.processName);
+ }
+ return false;
}
- if (force || !app.mOptRecord.hasPendingCompact()) {
- Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK,
- "compactAppSome " + app.processName != null ? app.processName : "");
- app.mOptRecord.setHasPendingCompact(true);
- app.mOptRecord.setForceCompact(force);
- mPendingCompactionProcesses.add(app);
- mCompactionHandler.sendMessage(
- mCompactionHandler.obtainMessage(
- COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
+
+ if (proc.mState.hasForegroundActivities()) {
+ if (DEBUG_COMPACTION) {
+ Slog.e(TAG_AM,
+ "Skip compaction as process " + proc.processName
+ + " has foreground activities");
+ }
+ return false;
}
+
+ return true;
}
@GuardedBy("mProcLock")
@@ -508,19 +522,7 @@
// Apply OOM adj score throttle for Full App Compaction.
if (force || oomAdjEnteredCached) {
app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_FULL);
- if (!app.mOptRecord.hasPendingCompact()) {
- Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK,
- "compactAppFull " + app.processName != null ? app.processName : "");
- app.mOptRecord.setHasPendingCompact(true);
- app.mOptRecord.setForceCompact(force);
- mPendingCompactionProcesses.add(app);
- mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage(
- COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState()));
- } else if (DEBUG_COMPACTION) {
- Slog.d(TAG_AM,
- " compactAppFull Skipped for " + app.processName
- + " since it has a pending compact");
- }
+ compactApp(app, force, "Full");
} else {
if (DEBUG_COMPACTION) {
Slog.d(TAG_AM, "Skipping full compaction for " + app.processName
@@ -533,15 +535,34 @@
@GuardedBy("mProcLock")
void compactAppPersistent(ProcessRecord app) {
app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_PERSISTENT);
- if (!app.mOptRecord.hasPendingCompact()) {
+ compactApp(app, false, "Persistent");
+ }
+
+ @GuardedBy("mProcLock")
+ boolean compactApp(ProcessRecord app, boolean force, String compactRequestType) {
+ if (!app.mOptRecord.hasPendingCompact() && meetsCompactionRequirements(app)) {
+ final String processName = (app.processName != null ? app.processName : "");
+ if (DEBUG_COMPACTION) {
+ Slog.d(TAG_AM, "compactApp " + compactRequestType + " " + processName);
+ }
Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK,
- "compactAppPersistent " + app.processName != null ? app.processName : "");
+ "compactApp " + compactRequestType + " " + processName);
app.mOptRecord.setHasPendingCompact(true);
+ app.mOptRecord.setForceCompact(force);
mPendingCompactionProcesses.add(app);
- mCompactionHandler.sendMessage(
- mCompactionHandler.obtainMessage(
+ mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage(
COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState()));
+ return true;
}
+
+ if (DEBUG_COMPACTION) {
+ Slog.d(TAG_AM,
+ " compactApp Skipped for " + app.processName
+ + " pendingCompact= " + app.mOptRecord.hasPendingCompact()
+ + " meetsCompactionRequirements=" + meetsCompactionRequirements(app)
+ + ". Requested compact: " + app.mOptRecord.getReqCompactAction());
+ }
+ return false;
}
@GuardedBy("mProcLock")
@@ -553,15 +574,7 @@
@GuardedBy("mProcLock")
void compactAppBfgs(ProcessRecord app) {
app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_BFGS);
- if (!app.mOptRecord.hasPendingCompact()) {
- Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK,
- "compactAppBfgs " + app.processName != null ? app.processName : "");
- app.mOptRecord.setHasPendingCompact(true);
- mPendingCompactionProcesses.add(app);
- mCompactionHandler.sendMessage(
- mCompactionHandler.obtainMessage(
- COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState()));
- }
+ compactApp(app, false, " Bfgs");
}
@GuardedBy("mProcLock")
@@ -572,6 +585,9 @@
void compactAllSystem() {
if (useCompaction()) {
+ if (DEBUG_COMPACTION) {
+ Slog.d(TAG_AM, "compactAllSystem");
+ }
Trace.instantForTrack(
Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK, "compactAllSystem");
mCompactionHandler.sendMessage(mCompactionHandler.obtainMessage(
@@ -1175,13 +1191,13 @@
cancelCompaction();
}
- // Perform a minor compaction when a perceptible app becomes the prev/home app
- // Perform a major compaction when any app enters cached
if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ
&& (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) {
+ // Perform a minor compaction when a perceptible app becomes the prev/home app
compactAppSome(app, false);
} else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ
&& newAdj <= ProcessList.CACHED_APP_MAX_ADJ) {
+ // Perform a major compaction when any app enters cached
compactAppFull(app, false);
}
}
@@ -1241,12 +1257,6 @@
private boolean shouldOomAdjThrottleCompaction(ProcessRecord proc, int action) {
final String name = proc.processName;
- if (mAm.mInternal.isPendingTopUid(proc.uid)) {
- // In case the OOM Adjust has not yet been propagated we see if this is
- // pending on becoming top app in which case we should not compact.
- Slog.e(TAG_AM, "Skip compaction since UID is active for " + name);
- return true;
- }
// don't compact if the process has returned to perceptible
// and this is only a cached/home/prev compaction
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index b6757c8..17fff91 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -72,7 +72,7 @@
Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
Context.BIND_FOREGROUND_SERVICE,
Context.BIND_TREAT_LIKE_ACTIVITY,
- Context.BIND_VISIBLE,
+ Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
Context.BIND_SHOWING_UI,
Context.BIND_NOT_VISIBLE,
Context.BIND_NOT_PERCEPTIBLE,
@@ -225,8 +225,8 @@
if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) {
sb.append("SLTA ");
}
- if ((flags&Context.BIND_VISIBLE) != 0) {
- sb.append("VIS ");
+ if ((flags & Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE) != 0) {
+ sb.append("VFGS ");
}
if ((flags&Context.BIND_SHOWING_UI) != 0) {
sb.append("UI ");
diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java
index 18fb6a4..08a6719 100644
--- a/services/core/java/com/android/server/am/DropboxRateLimiter.java
+++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java
@@ -24,9 +24,14 @@
/** Rate limiter for adding errors into dropbox. */
public class DropboxRateLimiter {
- private static final long RATE_LIMIT_BUFFER_EXPIRY = 15 * DateUtils.SECOND_IN_MILLIS;
- private static final long RATE_LIMIT_BUFFER_DURATION = 10 * DateUtils.SECOND_IN_MILLIS;
- private static final int RATE_LIMIT_ALLOWED_ENTRIES = 5;
+ // After RATE_LIMIT_ALLOWED_ENTRIES have been collected (for a single breakdown of
+ // process/eventType) further entries will be rejected until RATE_LIMIT_BUFFER_DURATION has
+ // elapsed, after which the current count for this breakdown will be reset.
+ private static final long RATE_LIMIT_BUFFER_DURATION = 10 * DateUtils.MINUTE_IN_MILLIS;
+ // The time duration after which the rate limit buffer will be cleared.
+ private static final long RATE_LIMIT_BUFFER_EXPIRY = 3 * RATE_LIMIT_BUFFER_DURATION;
+ // The number of entries to keep per breakdown of process/eventType.
+ private static final int RATE_LIMIT_ALLOWED_ENTRIES = 6;
@GuardedBy("mErrorClusterRecords")
private final ArrayMap<String, ErrorRecord> mErrorClusterRecords = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/am/ErrorDialogController.java b/services/core/java/com/android/server/am/ErrorDialogController.java
index a4e8f92..82f35ad 100644
--- a/services/core/java/com/android/server/am/ErrorDialogController.java
+++ b/services/core/java/com/android/server/am/ErrorDialogController.java
@@ -144,7 +144,8 @@
if (mWaitDialog == null) {
return;
}
- mWaitDialog.dismiss();
+ final BaseErrorDialog dialog = mWaitDialog;
+ mService.mUiHandler.post(dialog::dismiss);
mWaitDialog = null;
}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 4d10574..e7fcc59 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -39,6 +39,7 @@
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+import static android.content.Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
@@ -2061,6 +2062,10 @@
newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
} else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
newAdj = clientAdj;
+ } else if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)
+ && clientAdj <= ProcessList.VISIBLE_APP_ADJ
+ && adj > ProcessList.VISIBLE_APP_ADJ) {
+ newAdj = ProcessList.VISIBLE_APP_ADJ;
} else {
if (adj > ProcessList.VISIBLE_APP_ADJ) {
// TODO: Is this too limiting for apps bound from TOP?
@@ -2097,7 +2102,9 @@
// processes). These should not bring the current process
// into the top state, since they are not on top. Instead
// give them the best bound state after that.
- if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
+ if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)) {
+ clientProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+ } else if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else if (mService.mWakefulness.get()
== PowerManagerInternal.WAKEFULNESS_AWAKE
@@ -2556,20 +2563,21 @@
// reminder: here, setAdj is previous state, curAdj is upcoming state
if (state.getCurAdj() != state.getSetAdj()) {
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
- } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
- && state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
- && !state.isRunningRemoteAnimation()
- // Because these can fire independent of oom_adj/procstate changes, we need
- // to throttle the actual dispatch of these requests in addition to the
- // processing of the requests. As a result, there is throttling both here
- // and in CachedAppOptimizer.
- && mCachedAppOptimizer.shouldCompactPersistent(app, now)) {
- mCachedAppOptimizer.compactAppPersistent(app);
- } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE
- && state.getCurProcState()
- == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- && mCachedAppOptimizer.shouldCompactBFGS(app, now)) {
- mCachedAppOptimizer.compactAppBfgs(app);
+ } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE) {
+ // See if we can compact persistent and bfgs services now that screen is off
+ if (state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ
+ && !state.isRunningRemoteAnimation()
+ // Because these can fire independent of oom_adj/procstate changes, we need
+ // to throttle the actual dispatch of these requests in addition to the
+ // processing of the requests. As a result, there is throttling both here
+ // and in CachedAppOptimizer.
+ && mCachedAppOptimizer.shouldCompactPersistent(app, now)) {
+ mCachedAppOptimizer.compactAppPersistent(app);
+ } else if (state.getCurProcState()
+ == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+ && mCachedAppOptimizer.shouldCompactBFGS(app, now)) {
+ mCachedAppOptimizer.compactAppBfgs(app);
+ }
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index fc73a59..cceacd8 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2792,6 +2792,15 @@
}
int N = procs.size();
+ for (int i = 0; i < N; ++i) {
+ final ProcessRecord proc = procs.get(i).first;
+ try {
+ Process.setProcessFrozen(proc.getPid(), proc.uid, true);
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to freeze " + proc.getPid() + " " + proc.processName);
+ }
+ }
+
for (int i=0; i<N; i++) {
final Pair<ProcessRecord, Boolean> proc = procs.get(i);
removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 3e97b91..36afb36 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -4545,8 +4545,9 @@
* @return The restriction matching the package
*/
private RestrictionBypass getBypassforPackage(@NonNull AndroidPackage pkg) {
- return new RestrictionBypass(pkg.isPrivileged(), mContext.checkPermission(
- android.Manifest.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS, -1, pkg.getUid())
+ return new RestrictionBypass(pkg.getUid() == Process.SYSTEM_UID, pkg.isPrivileged(),
+ mContext.checkPermission(android.Manifest.permission
+ .EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS, -1, pkg.getUid())
== PackageManager.PERMISSION_GRANTED);
}
@@ -4853,6 +4854,9 @@
if (opBypass != null) {
// If we are the system, bypass user restrictions for certain codes
synchronized (this) {
+ if (opBypass.isSystemUid && appBypass != null && appBypass.isSystemUid) {
+ return false;
+ }
if (opBypass.isPrivileged && appBypass != null && appBypass.isPrivileged) {
return false;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 1f3fbff..aed63ce 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -9135,6 +9135,8 @@
if (timeOutMs <= 0 || usages.length == 0) {
throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
}
+ Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
+ + " usages:" + usages);
if (mDeviceBroker.isDeviceConnected(device)) {
// not throwing an exception as there could be a race between a connection (server-side,
@@ -9178,7 +9180,7 @@
Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
return;
}
- if (!device.equals(mMutingExpectedDevice)) {
+ if (!device.equalTypeAddress(mMutingExpectedDevice)) {
Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
+ "] but expected device is" + mMutingExpectedDevice);
throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 74c8999..565783f 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -1158,6 +1158,8 @@
//==========================================================================================
void muteAwaitConnection(@NonNull int[] usagesToMute,
@NonNull AudioDeviceAttributes dev, long timeOutMs) {
+ sEventLogger.loglogi(
+ "muteAwaitConnection() dev:" + dev + " timeOutMs:" + timeOutMs, TAG);
synchronized (mPlayerLock) {
mutePlayersExpectingDevice(usagesToMute);
// schedule timeout (remove previously scheduled first)
@@ -1169,6 +1171,7 @@
}
void cancelMuteAwaitConnection() {
+ sEventLogger.loglogi("cancelMuteAwaitConnection()", TAG);
synchronized (mPlayerLock) {
// cancel scheduled timeout, ignore device, only one expected device at a time
mEventHandler.removeMessages(MSG_L_TIMEOUT_MUTE_AWAIT_CONNECTION);
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 122a950..d8aa9aa 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -486,8 +486,7 @@
for (SADeviceState deviceState : mSADevices) {
if (deviceType == deviceState.mDeviceType
- && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
- || !wireless) {
+ && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) {
isInList = true;
if (forceEnable) {
deviceState.mEnabled = true;
@@ -511,8 +510,7 @@
for (SADeviceState deviceState : mSADevices) {
if (deviceType == deviceState.mDeviceType
- && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
- || !wireless) {
+ && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) {
deviceState.mEnabled = false;
break;
}
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index b5c8cd1..bc550d3 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -805,9 +805,10 @@
if (isUdfps && udfpsProps.length == 3) {
return new FingerprintSensorPropertiesInternal(sensorId,
Utils.authenticatorStrengthToPropertyStrength(strength), maxEnrollmentsPerUser,
- componentInfo, sensorType, resetLockoutRequiresHardwareAuthToken,
- List.of(new SensorLocationInternal("" /* display */,
- udfpsProps[0], udfpsProps[1], udfpsProps[2])));
+ componentInfo, sensorType, true /* halControlsIllumination */,
+ resetLockoutRequiresHardwareAuthToken,
+ List.of(new SensorLocationInternal("" /* display */, udfpsProps[0],
+ udfpsProps[1], udfpsProps[2])));
} else {
return new FingerprintSensorPropertiesInternal(sensorId,
Utils.authenticatorStrengthToPropertyStrength(strength), maxEnrollmentsPerUser,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 998a8e1..a600f08 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -176,6 +176,7 @@
prop.commonProps.maxEnrollmentsPerUser,
componentInfo,
prop.sensorType,
+ prop.halControlsIllumination,
true /* resetLockoutRequiresHardwareAuthToken */,
!workaroundLocations.isEmpty() ? workaroundLocations :
Arrays.stream(prop.sensorLocations).map(location ->
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index 485a674..bea0f4f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -400,7 +400,7 @@
.getInteger(R.integer.config_fingerprintMaxTemplatesPerUser);
mSensorProperties = new FingerprintSensorPropertiesInternal(sensorProps.sensorId,
sensorProps.sensorStrength, maxTemplatesAllowed, sensorProps.componentInfo,
- FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, false /* halControlsIllumination */,
resetLockoutRequiresHardwareAuthToken, sensorProps.getAllLocations());
mMockHalResultController = controller;
mUserHasTrust = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index be11253..bdd5b3d 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -24,6 +24,7 @@
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.admin.DevicePolicyManager;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
@@ -576,6 +577,16 @@
updateActivityCount(cameraState);
}
+
+ @Override
+ public boolean isCameraDisabled() {
+ DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+ if (dpm == null) {
+ Slog.e(TAG, "Failed to get the device policy manager service");
+ return false;
+ }
+ return dpm.getCameraDisabled(null);
+ }
};
private final FoldStateListener mFoldStateListener;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5fcdc8a..2cf11c6 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -103,8 +103,6 @@
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfigInterface;
import android.provider.Settings;
import android.sysprop.DisplayProperties;
import android.text.TextUtils;
@@ -406,7 +404,6 @@
private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
private final Injector mInjector;
- private final DeviceConfigInterface mDeviceConfig;
// The minimum brightness curve, which guarantess that any brightness curve that dips below it
// is rejected by the system.
@@ -483,7 +480,6 @@
DisplayManagerService(Context context, Injector injector) {
super(context);
mInjector = injector;
- mDeviceConfig = mInjector.getDeviceConfig();
mContext = context;
mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
mUiHandler = UiThread.getHandler();
@@ -1332,21 +1328,6 @@
"Requires ADD_ALWAYS_UNLOCKED_DISPLAY permission to "
+ "create an always unlocked virtual display.");
}
- boolean allowedByDeviceConfig = false;
- final long token = Binder.clearCallingIdentity();
- try {
- allowedByDeviceConfig = mDeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
- DisplayManager.DeviceConfig.KEY_ALLOW_ALWAYS_UNLOCKED_VIRTUAL_DISPLAYS,
- false);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (!allowedByDeviceConfig) {
- Slog.w(TAG, "Ignoring flag VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED "
- + "because it is not allowed by DeviceConfig");
- flags &= ~VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
- }
}
if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
@@ -1459,16 +1440,6 @@
DisplayDevice device =
mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
if (device != null) {
- final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
- if (display != null) {
- final int displayId = display.getDisplayIdLocked();
- if (mDisplayWindowPolicyControllers.contains(displayId)) {
- Pair<IVirtualDevice, DisplayWindowPolicyController> pair =
- mDisplayWindowPolicyControllers.removeReturnOld(displayId);
- getLocalService(VirtualDeviceManagerInternal.class)
- .onVirtualDisplayRemoved(pair.first, displayId);
- }
- }
// TODO: multi-display - handle virtual displays the same as other display adapters.
mDisplayDeviceRepo.onDisplayDeviceEvent(device,
DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
@@ -1628,6 +1599,17 @@
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
scheduleTraversalLocked(false);
+
+ if (mDisplayWindowPolicyControllers.contains(displayId)) {
+ final IVirtualDevice virtualDevice = mDisplayWindowPolicyControllers.removeReturnOld(
+ displayId).first;
+ if (virtualDevice != null) {
+ mHandler.post(() -> {
+ getLocalService(VirtualDeviceManagerInternal.class)
+ .onVirtualDisplayRemoved(virtualDevice, displayId);
+ });
+ }
+ }
}
private void handleLogicalDisplaySwappedLocked(@NonNull LogicalDisplay display) {
@@ -2562,11 +2544,6 @@
return DisplayProperties
.debug_allow_non_native_refresh_rate_override().orElse(true);
}
-
- @NonNull
- public DeviceConfigInterface getDeviceConfig() {
- return DeviceConfigInterface.REAL;
- }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8ab0b93..e4e9d1d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -164,6 +164,7 @@
private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
private static final int MSG_RELOAD_DEVICE_ALIASES = 5;
private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6;
+ private static final int MSG_POINTER_DISPLAY_ID_CHANGED = 7;
private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
@@ -276,11 +277,24 @@
@GuardedBy("mAssociationLock")
private final Map<String, String> mUniqueIdAssociations = new ArrayMap<>();
+ // Guards per-display input properties and properties relating to the mouse pointer.
+ // Threads can wait on this lock to be notified the next time the display on which the mouse
+ // pointer is shown has changed.
private final Object mAdditionalDisplayInputPropertiesLock = new Object();
- // Forces the MouseCursorController to target a specific display id.
+ // Forces the PointerController to target a specific display id.
@GuardedBy("mAdditionalDisplayInputPropertiesLock")
private int mOverriddenPointerDisplayId = Display.INVALID_DISPLAY;
+
+ // PointerController is the source of truth of the pointer display. This is the value of the
+ // latest pointer display id reported by PointerController.
+ @GuardedBy("mAdditionalDisplayInputPropertiesLock")
+ private int mAcknowledgedPointerDisplayId = Display.INVALID_DISPLAY;
+ // This is the latest display id that IMS has requested PointerController to use. If there are
+ // no devices that can control the pointer, PointerController may end up disregarding this
+ // value.
+ @GuardedBy("mAdditionalDisplayInputPropertiesLock")
+ private int mRequestedPointerDisplayId = Display.INVALID_DISPLAY;
@GuardedBy("mAdditionalDisplayInputPropertiesLock")
private final SparseArray<AdditionalDisplayInputProperties> mAdditionalDisplayInputProperties =
new SparseArray<>();
@@ -289,7 +303,6 @@
@GuardedBy("mAdditionalDisplayInputPropertiesLock")
private PointerIcon mIcon;
-
// Holds all the registered gesture monitors that are implemented as spy windows. The spy
// windows are mapped by their InputChannel tokens.
@GuardedBy("mInputMonitors")
@@ -383,6 +396,10 @@
NativeInputManagerService getNativeService(InputManagerService service) {
return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
}
+
+ void registerLocalService(InputManagerInternal localService) {
+ LocalServices.addService(InputManagerInternal.class, localService);
+ }
}
public InputManagerService(Context context) {
@@ -391,11 +408,14 @@
@VisibleForTesting
InputManagerService(Injector injector) {
+ // The static association map is accessed by both java and native code, so it must be
+ // initialized before initializing the native service.
+ mStaticAssociations = loadStaticInputPortAssociations();
+
mContext = injector.getContext();
mHandler = new InputManagerHandler(injector.getLooper());
mNative = injector.getNativeService(this);
- mStaticAssociations = loadStaticInputPortAssociations();
mUseDevInputEventForAudioJack =
mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
@@ -406,7 +426,7 @@
mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
new File(doubleTouchGestureEnablePath);
- LocalServices.addService(InputManagerInternal.class, new LocalService());
+ injector.registerLocalService(new LocalService());
}
public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
@@ -556,6 +576,8 @@
vArray[i] = viewports.get(i);
}
mNative.setDisplayViewports(vArray);
+ // Always attempt to update the pointer display when viewports change.
+ updatePointerDisplayId();
if (mOverriddenPointerDisplayId != Display.INVALID_DISPLAY) {
final AdditionalDisplayInputProperties properties =
@@ -1690,6 +1712,13 @@
mPointerIconDisplayContext = null;
}
+ synchronized (mAdditionalDisplayInputPropertiesLock) {
+ setPointerIconVisible(AdditionalDisplayInputProperties.DEFAULT_POINTER_ICON_VISIBLE,
+ displayId);
+ setPointerAcceleration(AdditionalDisplayInputProperties.DEFAULT_POINTER_ACCELERATION,
+ displayId);
+ }
+
mNative.displayRemoved(displayId);
}
@@ -1961,10 +1990,43 @@
return result;
}
- private void setVirtualMousePointerDisplayId(int displayId) {
+ /**
+ * Update the display on which the mouse pointer is shown.
+ * If there is an overridden display for the mouse pointer, use that. Otherwise, query
+ * WindowManager for the pointer display.
+ *
+ * @return true if the pointer displayId changed, false otherwise.
+ */
+ private boolean updatePointerDisplayId() {
+ synchronized (mAdditionalDisplayInputPropertiesLock) {
+ final int pointerDisplayId = mOverriddenPointerDisplayId != Display.INVALID_DISPLAY
+ ? mOverriddenPointerDisplayId : mWindowManagerCallbacks.getPointerDisplayId();
+ if (mRequestedPointerDisplayId == pointerDisplayId) {
+ return false;
+ }
+ mRequestedPointerDisplayId = pointerDisplayId;
+ mNative.setPointerDisplayId(pointerDisplayId);
+ return true;
+ }
+ }
+
+ private void handlePointerDisplayIdChanged(PointerDisplayIdChangedArgs args) {
+ synchronized (mAdditionalDisplayInputPropertiesLock) {
+ mAcknowledgedPointerDisplayId = args.mPointerDisplayId;
+ // Notify waiting threads that the display of the mouse pointer has changed.
+ mAdditionalDisplayInputPropertiesLock.notifyAll();
+ }
+ mWindowManagerCallbacks.notifyPointerDisplayIdChanged(
+ args.mPointerDisplayId, args.mXPosition, args.mYPosition);
+ }
+
+ private boolean setVirtualMousePointerDisplayIdBlocking(int displayId) {
+ // Indicates whether this request is for removing the override.
+ final boolean removingOverride = displayId == Display.INVALID_DISPLAY;
+
synchronized (mAdditionalDisplayInputPropertiesLock) {
mOverriddenPointerDisplayId = displayId;
- if (displayId != Display.INVALID_DISPLAY) {
+ if (!removingOverride) {
final AdditionalDisplayInputProperties properties =
mAdditionalDisplayInputProperties.get(displayId);
if (properties != null) {
@@ -1972,9 +2034,30 @@
updatePointerIconVisibleLocked(properties.pointerIconVisible);
}
}
+ if (!updatePointerDisplayId() && mAcknowledgedPointerDisplayId == displayId) {
+ // The requested pointer display is already set.
+ return true;
+ }
+ if (removingOverride && mAcknowledgedPointerDisplayId == Display.INVALID_DISPLAY) {
+ // The pointer display override is being removed, but the current pointer display
+ // is already invalid. This can happen when the PointerController is destroyed as a
+ // result of the removal of all input devices that can control the pointer.
+ return true;
+ }
+ try {
+ // The pointer display changed, so wait until the change has propagated.
+ mAdditionalDisplayInputPropertiesLock.wait(5_000 /*mills*/);
+ } catch (InterruptedException ignored) {
+ }
+ // This request succeeds in two cases:
+ // - This request was to remove the override, in which case the new pointer display
+ // could be anything that WM has set.
+ // - We are setting a new override, in which case the request only succeeds if the
+ // reported new displayId is the one we requested. This check ensures that if two
+ // competing overrides are requested in succession, the caller can be notified if one
+ // of them fails.
+ return removingOverride || mAcknowledgedPointerDisplayId == displayId;
}
- // TODO(b/215597605): trigger MousePositionTracker update
- mNative.notifyPointerDisplayIdChanged();
}
private int getVirtualMousePointerDisplayId() {
@@ -3156,18 +3239,6 @@
// Native callback.
@SuppressWarnings("unused")
- private int getPointerDisplayId() {
- synchronized (mAdditionalDisplayInputPropertiesLock) {
- // Prefer the override to all other displays.
- if (mOverriddenPointerDisplayId != Display.INVALID_DISPLAY) {
- return mOverriddenPointerDisplayId;
- }
- }
- return mWindowManagerCallbacks.getPointerDisplayId();
- }
-
- // Native callback.
- @SuppressWarnings("unused")
private String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) {
if (!mSystemReady) {
return null;
@@ -3206,6 +3277,26 @@
return null;
}
+ private static class PointerDisplayIdChangedArgs {
+ final int mPointerDisplayId;
+ final float mXPosition;
+ final float mYPosition;
+ PointerDisplayIdChangedArgs(int pointerDisplayId, float xPosition, float yPosition) {
+ mPointerDisplayId = pointerDisplayId;
+ mXPosition = xPosition;
+ mYPosition = yPosition;
+ }
+ }
+
+ // Native callback.
+ @SuppressWarnings("unused")
+ @VisibleForTesting
+ void onPointerDisplayIdChanged(int pointerDisplayId, float xPosition, float yPosition) {
+ mHandler.obtainMessage(MSG_POINTER_DISPLAY_ID_CHANGED,
+ new PointerDisplayIdChangedArgs(pointerDisplayId, xPosition,
+ yPosition)).sendToTarget();
+ }
+
/**
* Callback interface implemented by the Window Manager.
*/
@@ -3329,6 +3420,14 @@
*/
@Nullable
SurfaceControl createSurfaceForGestureMonitor(String name, int displayId);
+
+ /**
+ * Notify WindowManagerService when the display of the mouse pointer changes.
+ * @param displayId The display on which the mouse pointer is shown.
+ * @param x The x coordinate of the mouse pointer.
+ * @param y The y coordinate of the mouse pointer.
+ */
+ void notifyPointerDisplayIdChanged(int displayId, float x, float y);
}
/**
@@ -3381,6 +3480,9 @@
boolean inTabletMode = (boolean) args.arg1;
deliverTabletModeChanged(whenNanos, inTabletMode);
break;
+ case MSG_POINTER_DISPLAY_ID_CHANGED:
+ handlePointerDisplayIdChanged((PointerDisplayIdChangedArgs) msg.obj);
+ break;
}
}
}
@@ -3631,8 +3733,9 @@
}
@Override
- public void setVirtualMousePointerDisplayId(int pointerDisplayId) {
- InputManagerService.this.setVirtualMousePointerDisplayId(pointerDisplayId);
+ public boolean setVirtualMousePointerDisplayId(int pointerDisplayId) {
+ return InputManagerService.this
+ .setVirtualMousePointerDisplayIdBlocking(pointerDisplayId);
}
@Override
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 2169155..81882d2 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -176,6 +176,9 @@
void cancelCurrentTouch();
+ /** Set the displayId on which the mouse cursor should be shown. */
+ void setPointerDisplayId(int displayId);
+
/** The native implementation of InputManagerService methods. */
class NativeImpl implements NativeInputManagerService {
/** Pointer to native input manager service object, used by native code. */
@@ -388,5 +391,8 @@
@Override
public native void cancelCurrentTouch();
+
+ @Override
+ public native void setPointerDisplayId(int displayId);
}
}
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index db17c105..8180e66 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -64,7 +64,9 @@
| InputConfig.INTERCEPTS_STYLUS
| InputConfig.TRUSTED_OVERLAY;
- // The touchable region of this input surface is not initially configured.
+ // Configure the surface to receive stylus events across the entire display.
+ mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, HANDWRITING_SURFACE_LAYER);
@@ -81,10 +83,6 @@
mWindowHandle.ownerUid = imeUid;
mWindowHandle.inputConfig &= ~InputConfig.SPY;
- // Update the touchable region so that the IME can intercept stylus events
- // across the entire display.
- mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
-
new SurfaceControl.Transaction()
.setInputWindowInfo(mInputSurface, mWindowHandle)
.apply();
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index a706772..f89b6ae 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -91,7 +91,7 @@
* InputEventReceiver that batches events according to the current thread's Choreographer.
*/
@UiThread
- void initializeHandwritingSpy(int displayId, IBinder focusedWindowToken) {
+ void initializeHandwritingSpy(int displayId) {
// When resetting, reuse resources if we are reinitializing on the same display.
reset(displayId == mCurrentDisplayId);
mCurrentDisplayId = displayId;
@@ -115,12 +115,6 @@
mHandwritingSurface = new HandwritingEventReceiverSurface(
name, displayId, surface, channel);
- // Configure the handwriting window to receive events over the focused window's bounds.
- mWindowManagerInternal.replaceInputSurfaceTouchableRegionWithWindowCrop(
- mHandwritingSurface.getSurface(),
- mHandwritingSurface.getInputWindowHandle(),
- focusedWindowToken);
-
// Use a dup of the input channel so that event processing can be paused by disposing the
// event receiver without causing a fd hangup.
mHandwritingEventReceiver = new BatchedInputEventReceiver.SimpleBatchedInputEventReceiver(
@@ -149,7 +143,8 @@
*/
@UiThread
@Nullable
- HandwritingSession startHandwritingSession(int requestId, int imePid, int imeUid) {
+ HandwritingSession startHandwritingSession(
+ int requestId, int imePid, int imeUid, IBinder focusedWindowToken) {
if (mHandwritingSurface == null) {
Slog.e(TAG, "Cannot start handwriting session: Handwriting was not initialized.");
return null;
@@ -158,12 +153,20 @@
Slog.e(TAG, "Cannot start handwriting session: Invalid request id: " + requestId);
return null;
}
- if (!mRecordingGesture) {
+ if (!mRecordingGesture || mHandwritingBuffer.isEmpty()) {
Slog.e(TAG, "Cannot start handwriting session: No stylus gesture is being recorded.");
return null;
}
Objects.requireNonNull(mHandwritingEventReceiver,
"Handwriting session was already transferred to IME.");
+ final MotionEvent downEvent = mHandwritingBuffer.get(0);
+ assert (downEvent.getActionMasked() == MotionEvent.ACTION_DOWN);
+ if (!mWindowManagerInternal.isPointInsideWindow(
+ focusedWindowToken, mCurrentDisplayId, downEvent.getRawX(), downEvent.getRawY())) {
+ Slog.e(TAG, "Cannot start handwriting session: "
+ + "Stylus gesture did not start inside the focused window.");
+ return null;
+ }
if (DEBUG) Slog.d(TAG, "Starting handwriting session in display: " + mCurrentDisplayId);
mInputManagerInternal.pilferPointers(mHandwritingSurface.getInputChannel().getToken());
@@ -226,13 +229,17 @@
}
if (!(ev instanceof MotionEvent)) {
- Slog.e("Stylus", "Received non-motion event in stylus monitor.");
+ Slog.wtf(TAG, "Received non-motion event in stylus monitor.");
return false;
}
final MotionEvent event = (MotionEvent) ev;
if (!isStylusEvent(event)) {
return false;
}
+ if (event.getDisplayId() != mCurrentDisplayId) {
+ Slog.wtf(TAG, "Received stylus event associated with the incorrect display.");
+ return false;
+ }
onStylusEvent(event);
return true;
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
index e62c5c1..1703310 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
@@ -30,6 +30,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputMethodSubtype;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
@@ -148,10 +149,11 @@
@AnyThread
void startInput(IBinder startInputToken, IInputContext inputContext, EditorInfo attribute,
- boolean restarting, @InputMethodNavButtonFlags int navButtonFlags) {
+ boolean restarting, @InputMethodNavButtonFlags int navButtonFlags,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
try {
mTarget.startInput(startInputToken, inputContext, attribute, restarting,
- navButtonFlags);
+ navButtonFlags, imeDispatcher);
} catch (RemoteException e) {
logRemoteException(e);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6af00b3..ea2b157 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -150,6 +150,7 @@
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
+import android.window.ImeOnBackInvokedDispatcher;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
@@ -616,6 +617,12 @@
IInputContext mCurInputContext;
/**
+ * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
+ * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
+ */
+ ImeOnBackInvokedDispatcher mCurImeDispatcher;
+
+ /**
* The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
*/
@Nullable IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
@@ -2623,7 +2630,7 @@
final SessionState session = mCurClient.curSession;
setEnabledSessionLocked(session);
session.method.startInput(startInputToken, mCurInputContext, mCurAttribute, restarting,
- navButtonFlags);
+ navButtonFlags, mCurImeDispatcher);
if (mShowRequested) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlagsLocked(), null,
@@ -2733,7 +2740,8 @@
@Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
@NonNull EditorInfo attribute, @StartInputFlags int startInputFlags,
@StartInputReason int startInputReason,
- int unverifiedTargetSdkVersion) {
+ int unverifiedTargetSdkVersion,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
// If no method is currently selected, do nothing.
final String selectedMethodId = getSelectedMethodIdLocked();
if (selectedMethodId == null) {
@@ -2777,6 +2785,7 @@
mCurClient = cs;
mCurInputContext = inputContext;
mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
+ mCurImeDispatcher = imeDispatcher;
mCurVirtualDisplayToScreenMatrix =
getVirtualDisplayToScreenMatrixLocked(cs.selfReportedDisplayId,
mDisplayIdToShowIme);
@@ -3780,10 +3789,12 @@
@StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
int windowFlags, @Nullable EditorInfo attribute, IInputContext inputContext,
IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion) {
+ int unverifiedTargetSdkVersion,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
return startInputOrWindowGainedFocusInternal(startInputReason, client, windowToken,
startInputFlags, softInputMode, windowFlags, attribute, inputContext,
- remoteAccessibilityInputConnection, unverifiedTargetSdkVersion);
+ remoteAccessibilityInputConnection, unverifiedTargetSdkVersion,
+ imeDispatcher);
}
@NonNull
@@ -3792,7 +3803,8 @@
@StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
int windowFlags, @Nullable EditorInfo attribute, @Nullable IInputContext inputContext,
@Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion) {
+ int unverifiedTargetSdkVersion,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (windowToken == null) {
Slog.e(TAG, "windowToken cannot be null.");
return InputBindResult.NULL;
@@ -3829,7 +3841,7 @@
result = startInputOrWindowGainedFocusInternalLocked(startInputReason,
client, windowToken, startInputFlags, softInputMode, windowFlags,
attribute, inputContext, remoteAccessibilityInputConnection,
- unverifiedTargetSdkVersion, userId);
+ unverifiedTargetSdkVersion, userId, imeDispatcher);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3857,7 +3869,8 @@
@SoftInputModeFlags int softInputMode, int windowFlags, EditorInfo attribute,
IInputContext inputContext,
@Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
- int unverifiedTargetSdkVersion, @UserIdInt int userId) {
+ int unverifiedTargetSdkVersion, @UserIdInt int userId,
+ @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (DEBUG) {
Slog.v(TAG, "startInputOrWindowGainedFocusInternalLocked: reason="
+ InputMethodDebug.startInputReasonToString(startInputReason)
@@ -3868,7 +3881,8 @@
+ InputMethodDebug.startInputFlagsToString(startInputFlags)
+ " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
+ " windowFlags=#" + Integer.toHexString(windowFlags)
- + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion);
+ + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion
+ + " imeDispatcher=" + imeDispatcher);
}
final ClientState cs = mClients.get(client.asBinder());
@@ -3952,7 +3966,7 @@
if (attribute != null) {
return startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, attribute, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion);
+ startInputReason, unverifiedTargetSdkVersion, imeDispatcher);
}
return new InputBindResult(
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
@@ -3993,7 +4007,8 @@
if (isTextEditor && attribute != null
&& shouldRestoreImeVisibility(windowToken, softInputMode)) {
res = startInputUncheckedLocked(cs, inputContext, remoteAccessibilityInputConnection,
- attribute, startInputFlags, startInputReason, unverifiedTargetSdkVersion);
+ attribute, startInputFlags, startInputReason, unverifiedTargetSdkVersion,
+ imeDispatcher);
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY);
return res;
@@ -4033,7 +4048,8 @@
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, attribute, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion);
+ startInputReason, unverifiedTargetSdkVersion,
+ imeDispatcher);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
@@ -4065,7 +4081,8 @@
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, attribute, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion);
+ startInputReason, unverifiedTargetSdkVersion,
+ imeDispatcher);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
@@ -4085,7 +4102,8 @@
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, attribute, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion);
+ startInputReason, unverifiedTargetSdkVersion,
+ imeDispatcher);
didStart = true;
}
showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
@@ -4115,7 +4133,8 @@
}
res = startInputUncheckedLocked(cs, inputContext,
remoteAccessibilityInputConnection, attribute, startInputFlags,
- startInputReason, unverifiedTargetSdkVersion);
+ startInputReason, unverifiedTargetSdkVersion,
+ imeDispatcher);
} else {
res = InputBindResult.NULL_EDITOR_INFO;
}
@@ -5099,9 +5118,8 @@
case MSG_RESET_HANDWRITING: {
synchronized (ImfLock.class) {
if (mBindingController.supportsStylusHandwriting()
- && getCurMethodLocked() != null && mCurFocusedWindow != null) {
- mHwController.initializeHandwritingSpy(
- mCurTokenDisplayId, mCurFocusedWindow);
+ && getCurMethodLocked() != null) {
+ mHwController.initializeHandwritingSpy(mCurTokenDisplayId);
} else {
mHwController.reset();
}
@@ -5111,14 +5129,15 @@
case MSG_START_HANDWRITING:
synchronized (ImfLock.class) {
IInputMethodInvoker curMethod = getCurMethodLocked();
- if (curMethod == null) {
+ if (curMethod == null || mCurFocusedWindow == null) {
return true;
}
final HandwritingModeController.HandwritingSession session =
mHwController.startHandwritingSession(
msg.arg1 /*requestId*/,
msg.arg2 /*pid*/,
- mBindingController.getCurMethodUid());
+ mBindingController.getCurMethodUid(),
+ mCurFocusedWindow);
if (session == null) {
Slog.e(TAG,
"Failed to start handwriting session for requestId: " + msg.arg1);
diff --git a/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java
index 79088d0..f9a8407 100644
--- a/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java
+++ b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java
@@ -16,26 +16,28 @@
package com.android.server.logcat;
+import android.annotation.StyleRes;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
-import android.os.logcat.ILogcatManagerService;
import android.util.Slog;
+import android.view.ContextThemeWrapper;
import android.view.InflateException;
+import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.android.internal.R;
+import com.android.server.LocalServices;
/**
* Dialog responsible for obtaining user consent per-use log access
@@ -43,61 +45,61 @@
public class LogAccessDialogActivity extends Activity implements
View.OnClickListener {
private static final String TAG = LogAccessDialogActivity.class.getSimpleName();
- private Context mContext;
- private final ILogcatManagerService mLogcatManagerService =
- ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat"));
+ private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
+ private static final int MSG_DISMISS_DIALOG = 0;
+
+ private final LogcatManagerService.LogcatManagerServiceInternal mLogcatManagerInternal =
+ LocalServices.getService(LogcatManagerService.LogcatManagerServiceInternal.class);
private String mPackageName;
-
private int mUid;
- private int mGid;
- private int mPid;
- private int mFd;
+
private String mAlertTitle;
private AlertDialog.Builder mAlertDialog;
private AlertDialog mAlert;
private View mAlertView;
- private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
- private static final int MSG_DISMISS_DIALOG = 0;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- try {
- mContext = this;
-
- // retrieve Intent extra information
- Intent intent = getIntent();
- getIntentInfo(intent);
-
- // retrieve the title string from passed intent extra
- mAlertTitle = getTitleString(mContext, mPackageName, mUid);
-
- // creaet View
- mAlertView = createView();
-
- // create AlertDialog
- mAlertDialog = new AlertDialog.Builder(this);
- mAlertDialog.setView(mAlertView);
-
- // show Alert
- mAlert = mAlertDialog.create();
- mAlert.show();
-
- // set Alert Timeout
- mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT);
-
- } catch (Exception e) {
- try {
- Slog.e(TAG, "onCreate failed, declining the logd access", e);
- mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
- } catch (RemoteException ex) {
- Slog.e(TAG, "Fails to call remote functions", ex);
- }
+ // retrieve Intent extra information
+ if (!readIntentInfo(getIntent())) {
+ Slog.e(TAG, "Invalid Intent extras, finishing");
+ finish();
+ return;
}
+
+ // retrieve the title string from passed intent extra
+ try {
+ mAlertTitle = getTitleString(this, mPackageName, mUid);
+ } catch (NameNotFoundException e) {
+ Slog.e(TAG, "Unable to fetch label of package " + mPackageName, e);
+ declineLogAccess();
+ finish();
+ return;
+ }
+
+ // create View
+ boolean isDarkTheme = (getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
+ int themeId = isDarkTheme ? android.R.style.Theme_DeviceDefault_Dialog_Alert :
+ android.R.style.Theme_DeviceDefault_Light_Dialog_Alert;
+ mAlertView = createView(themeId);
+
+ // create AlertDialog
+ mAlertDialog = new AlertDialog.Builder(this, themeId);
+ mAlertDialog.setView(mAlertView);
+ mAlertDialog.setOnCancelListener(dialog -> declineLogAccess());
+ mAlertDialog.setOnDismissListener(dialog -> finish());
+
+ // show Alert
+ mAlert = mAlertDialog.create();
+ mAlert.show();
+
+ // set Alert Timeout
+ mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT);
}
@Override
@@ -109,21 +111,26 @@
mAlert = null;
}
- private void getIntentInfo(Intent intent) throws Exception {
-
+ private boolean readIntentInfo(Intent intent) {
if (intent == null) {
- throw new NullPointerException("Intent is null");
+ Slog.e(TAG, "Intent is null");
+ return false;
}
mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
if (mPackageName == null || mPackageName.length() == 0) {
- throw new NullPointerException("Package Name is null");
+ Slog.e(TAG, "Missing package name extra");
+ return false;
}
- mUid = intent.getIntExtra("com.android.server.logcat.uid", 0);
- mGid = intent.getIntExtra("com.android.server.logcat.gid", 0);
- mPid = intent.getIntExtra("com.android.server.logcat.pid", 0);
- mFd = intent.getIntExtra("com.android.server.logcat.fd", 0);
+ if (!intent.hasExtra(Intent.EXTRA_UID)) {
+ Slog.e(TAG, "Missing EXTRA_UID");
+ return false;
+ }
+
+ mUid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+
+ return true;
}
private Handler mHandler = new Handler() {
@@ -133,11 +140,7 @@
if (mAlert != null) {
mAlert.dismiss();
mAlert = null;
- try {
- mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
- }
+ declineLogAccess();
}
break;
@@ -148,25 +151,15 @@
};
private String getTitleString(Context context, String callingPackage, int uid)
- throws Exception {
-
+ throws NameNotFoundException {
PackageManager pm = context.getPackageManager();
- if (pm == null) {
- throw new NullPointerException("PackageManager is null");
- }
CharSequence appLabel = pm.getApplicationInfoAsUser(callingPackage,
PackageManager.MATCH_DIRECT_BOOT_AUTO,
UserHandle.getUserId(uid)).loadLabel(pm);
- if (appLabel == null || appLabel.length() == 0) {
- throw new NameNotFoundException("Application Label is null");
- }
String titleString = context.getString(
com.android.internal.R.string.log_access_confirmation_title, appLabel);
- if (titleString == null || titleString.length() == 0) {
- throw new NullPointerException("Title is null");
- }
return titleString;
}
@@ -176,9 +169,9 @@
* If we cannot retrieve the package name, it returns null and we decline the full device log
* access
*/
- private View createView() throws Exception {
-
- final View view = getLayoutInflater().inflate(
+ private View createView(@StyleRes int themeId) {
+ Context themedContext = new ContextThemeWrapper(getApplicationContext(), themeId);
+ final View view = LayoutInflater.from(themedContext).inflate(
R.layout.log_access_user_consent_dialog_permission, null /*root*/);
if (view == null) {
@@ -202,21 +195,17 @@
public void onClick(View view) {
switch (view.getId()) {
case R.id.log_access_dialog_allow_button:
- try {
- mLogcatManagerService.approve(mUid, mGid, mPid, mFd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
- }
+ mLogcatManagerInternal.approveAccessForClient(mUid, mPackageName);
finish();
break;
case R.id.log_access_dialog_deny_button:
- try {
- mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
- }
+ declineLogAccess();
finish();
break;
}
}
+
+ private void declineLogAccess() {
+ mLogcatManagerInternal.declineAccessForClient(mUid, mPackageName);
+ }
}
diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java
index 5dccd07..21beb96 100644
--- a/services/core/java/com/android/server/logcat/LogcatManagerService.java
+++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java
@@ -16,90 +16,322 @@
package com.android.server.logcat;
+import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Handler;
import android.os.ILogd;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.logcat.ILogcatManagerService;
+import android.util.ArrayMap;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Supplier;
/**
* Service responsible for managing the access to Logcat.
*/
public final class LogcatManagerService extends SystemService {
-
private static final String TAG = "LogcatManagerService";
+ private static final boolean DEBUG = false;
+
+ /** How long to wait for the user to approve/decline before declining automatically */
+ @VisibleForTesting
+ static final int PENDING_CONFIRMATION_TIMEOUT_MILLIS = Build.IS_DEBUGGABLE ? 70000 : 400000;
+
+ /**
+ * How long an approved / declined status is valid for.
+ *
+ * After a client has been approved/declined log access, if they try to access logs again within
+ * this timeout, the new request will be automatically approved/declined.
+ * Only after this timeout expires will a new request generate another prompt to the user.
+ **/
+ @VisibleForTesting
+ static final int STATUS_EXPIRATION_TIMEOUT_MILLIS = 60 * 1000;
+
+ private static final int MSG_LOG_ACCESS_REQUESTED = 0;
+ private static final int MSG_APPROVE_LOG_ACCESS = 1;
+ private static final int MSG_DECLINE_LOG_ACCESS = 2;
+ private static final int MSG_LOG_ACCESS_FINISHED = 3;
+ private static final int MSG_PENDING_TIMEOUT = 4;
+ private static final int MSG_LOG_ACCESS_STATUS_EXPIRED = 5;
+
+ private static final int STATUS_NEW_REQUEST = 0;
+ private static final int STATUS_PENDING = 1;
+ private static final int STATUS_APPROVED = 2;
+ private static final int STATUS_DECLINED = 3;
+
+ @IntDef(prefix = {"STATUS_"}, value = {
+ STATUS_NEW_REQUEST,
+ STATUS_PENDING,
+ STATUS_APPROVED,
+ STATUS_DECLINED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LogAccessRequestStatus {
+ }
+
private final Context mContext;
+ private final Injector mInjector;
+ private final Supplier<Long> mClock;
private final BinderService mBinderService;
- private final ExecutorService mThreadExecutor;
- private ILogd mLogdService;
- private @NonNull ActivityManager mActivityManager;
+ private final LogcatManagerServiceInternal mLocalService;
+ private final Handler mHandler;
private ActivityManagerInternal mActivityManagerInternal;
- private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2;
- private static final String TARGET_PACKAGE_NAME = "android";
- private static final String TARGET_ACTIVITY_NAME =
- "com.android.server.logcat.LogAccessDialogActivity";
- private static final String EXTRA_UID = "com.android.server.logcat.uid";
- private static final String EXTRA_GID = "com.android.server.logcat.gid";
- private static final String EXTRA_PID = "com.android.server.logcat.pid";
- private static final String EXTRA_FD = "com.android.server.logcat.fd";
+ private ILogd mLogdService;
+
+ private static final class LogAccessClient {
+ final int mUid;
+ @NonNull
+ final String mPackageName;
+
+ LogAccessClient(int uid, @NonNull String packageName) {
+ mUid = uid;
+ mPackageName = packageName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof LogAccessClient)) return false;
+ LogAccessClient that = (LogAccessClient) o;
+ return mUid == that.mUid && Objects.equals(mPackageName, that.mPackageName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUid, mPackageName);
+ }
+
+ @Override
+ public String toString() {
+ return "LogAccessClient{"
+ + "mUid=" + mUid
+ + ", mPackageName=" + mPackageName
+ + '}';
+ }
+ }
+
+ private static final class LogAccessRequest {
+ final int mUid;
+ final int mGid;
+ final int mPid;
+ final int mFd;
+
+ private LogAccessRequest(int uid, int gid, int pid, int fd) {
+ mUid = uid;
+ mGid = gid;
+ mPid = pid;
+ mFd = fd;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof LogAccessRequest)) return false;
+ LogAccessRequest that = (LogAccessRequest) o;
+ return mUid == that.mUid && mGid == that.mGid && mPid == that.mPid && mFd == that.mFd;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mUid, mGid, mPid, mFd);
+ }
+
+ @Override
+ public String toString() {
+ return "LogAccessRequest{"
+ + "mUid=" + mUid
+ + ", mGid=" + mGid
+ + ", mPid=" + mPid
+ + ", mFd=" + mFd
+ + '}';
+ }
+ }
+
+ private static final class LogAccessStatus {
+ @LogAccessRequestStatus
+ int mStatus = STATUS_NEW_REQUEST;
+ final List<LogAccessRequest> mPendingRequests = new ArrayList<>();
+ }
+
+ private final Map<LogAccessClient, LogAccessStatus> mLogAccessStatus = new ArrayMap<>();
+ private final Map<LogAccessClient, Integer> mActiveLogAccessCount = new ArrayMap<>();
private final class BinderService extends ILogcatManagerService.Stub {
@Override
public void startThread(int uid, int gid, int pid, int fd) {
- mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, true));
+ final LogAccessRequest logAccessRequest = new LogAccessRequest(uid, gid, pid, fd);
+ if (DEBUG) {
+ Slog.d(TAG, "New log access request: " + logAccessRequest);
+ }
+ final Message msg = mHandler.obtainMessage(MSG_LOG_ACCESS_REQUESTED, logAccessRequest);
+ mHandler.sendMessageAtTime(msg, mClock.get());
}
@Override
public void finishThread(int uid, int gid, int pid, int fd) {
- // TODO This thread will be used to notify the AppOpsManager that
- // the logd data access is finished.
- mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, false));
+ final LogAccessRequest logAccessRequest = new LogAccessRequest(uid, gid, pid, fd);
+ if (DEBUG) {
+ Slog.d(TAG, "Log access finished: " + logAccessRequest);
+ }
+ final Message msg = mHandler.obtainMessage(MSG_LOG_ACCESS_FINISHED, logAccessRequest);
+ mHandler.sendMessageAtTime(msg, mClock.get());
+ }
+ }
+
+ final class LogcatManagerServiceInternal {
+ public void approveAccessForClient(int uid, @NonNull String packageName) {
+ final LogAccessClient client = new LogAccessClient(uid, packageName);
+ if (DEBUG) {
+ Slog.d(TAG, "Approving log access for client: " + client);
+ }
+ final Message msg = mHandler.obtainMessage(MSG_APPROVE_LOG_ACCESS, client);
+ mHandler.sendMessageAtTime(msg, mClock.get());
}
- @Override
- public void approve(int uid, int gid, int pid, int fd) {
- try {
- Slog.d(TAG, "Allow logd access for uid: " + uid);
- getLogdService().approve(uid, gid, pid, fd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
+ public void declineAccessForClient(int uid, @NonNull String packageName) {
+ final LogAccessClient client = new LogAccessClient(uid, packageName);
+ if (DEBUG) {
+ Slog.d(TAG, "Declining log access for client: " + client);
}
- }
-
- @Override
- public void decline(int uid, int gid, int pid, int fd) {
- try {
- Slog.d(TAG, "Decline logd access for uid: " + uid);
- getLogdService().decline(uid, gid, pid, fd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
- }
+ final Message msg = mHandler.obtainMessage(MSG_DECLINE_LOG_ACCESS, client);
+ mHandler.sendMessageAtTime(msg, mClock.get());
}
}
private ILogd getLogdService() {
- synchronized (LogcatManagerService.this) {
- if (mLogdService == null) {
- LogcatManagerService.this.addLogdService();
- }
- return mLogdService;
+ if (mLogdService == null) {
+ mLogdService = mInjector.getLogdService();
}
+ return mLogdService;
+ }
+
+ private static class LogAccessRequestHandler extends Handler {
+ private final LogcatManagerService mService;
+
+ LogAccessRequestHandler(Looper looper, LogcatManagerService service) {
+ super(looper);
+ mService = service;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_LOG_ACCESS_REQUESTED: {
+ LogAccessRequest request = (LogAccessRequest) msg.obj;
+ mService.onLogAccessRequested(request);
+ break;
+ }
+ case MSG_APPROVE_LOG_ACCESS: {
+ LogAccessClient client = (LogAccessClient) msg.obj;
+ mService.onAccessApprovedForClient(client);
+ break;
+ }
+ case MSG_DECLINE_LOG_ACCESS: {
+ LogAccessClient client = (LogAccessClient) msg.obj;
+ mService.onAccessDeclinedForClient(client);
+ break;
+ }
+ case MSG_LOG_ACCESS_FINISHED: {
+ LogAccessRequest request = (LogAccessRequest) msg.obj;
+ mService.onLogAccessFinished(request);
+ break;
+ }
+ case MSG_PENDING_TIMEOUT: {
+ LogAccessClient client = (LogAccessClient) msg.obj;
+ mService.onPendingTimeoutExpired(client);
+ break;
+ }
+ case MSG_LOG_ACCESS_STATUS_EXPIRED: {
+ LogAccessClient client = (LogAccessClient) msg.obj;
+ mService.onAccessStatusExpired(client);
+ break;
+ }
+ }
+ }
+ }
+
+ static class Injector {
+ protected Supplier<Long> createClock() {
+ return SystemClock::uptimeMillis;
+ }
+
+ protected Looper getLooper() {
+ return Looper.getMainLooper();
+ }
+
+ protected ILogd getLogdService() {
+ return ILogd.Stub.asInterface(ServiceManager.getService("logd"));
+ }
+ }
+
+ public LogcatManagerService(Context context) {
+ this(context, new Injector());
+ }
+
+ public LogcatManagerService(Context context, Injector injector) {
+ super(context);
+ mContext = context;
+ mInjector = injector;
+ mClock = injector.createClock();
+ mBinderService = new BinderService();
+ mLocalService = new LogcatManagerServiceInternal();
+ mHandler = new LogAccessRequestHandler(injector.getLooper(), this);
+ }
+
+ @Override
+ public void onStart() {
+ try {
+ mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ publishBinderService("logcat", mBinderService);
+ publishLocalService(LogcatManagerServiceInternal.class, mLocalService);
+ } catch (Throwable t) {
+ Slog.e(TAG, "Could not start the LogcatManagerService.", t);
+ }
+ }
+
+ @VisibleForTesting
+ LogcatManagerServiceInternal getLocalService() {
+ return mLocalService;
+ }
+
+ @VisibleForTesting
+ ILogcatManagerService getBinderService() {
+ return mBinderService;
+ }
+
+ @Nullable
+ private LogAccessClient getClientForRequest(LogAccessRequest request) {
+ final String packageName = getPackageName(request);
+ if (packageName == null) {
+ return null;
+ }
+
+ return new LogAccessClient(request.mUid, packageName);
}
/**
@@ -107,12 +339,9 @@
* If we cannot retrieve the package name, it returns null and we decline the full device log
* access
*/
- private String getPackageName(int uid, int gid, int pid, int fd) {
-
- final ActivityManagerInternal activityManagerInternal =
- LocalServices.getService(ActivityManagerInternal.class);
- if (activityManagerInternal != null) {
- String packageName = activityManagerInternal.getPackageNameByPid(pid);
+ private String getPackageName(LogAccessRequest request) {
+ if (mActivityManagerInternal != null) {
+ String packageName = mActivityManagerInternal.getPackageNameByPid(request.mPid);
if (packageName != null) {
return packageName;
}
@@ -125,7 +354,7 @@
return null;
}
- String[] packageNames = pm.getPackagesForUid(uid);
+ String[] packageNames = pm.getPackagesForUid(request.mUid);
if (ArrayUtils.isEmpty(packageNames)) {
// Decline the logd access if the app name is unknown
@@ -142,127 +371,164 @@
}
return firstPackageName;
-
}
- private void declineLogdAccess(int uid, int gid, int pid, int fd) {
+ void onLogAccessRequested(LogAccessRequest request) {
+ final LogAccessClient client = getClientForRequest(request);
+ if (client == null) {
+ declineRequest(request);
+ return;
+ }
+
+ LogAccessStatus logAccessStatus = mLogAccessStatus.get(client);
+ if (logAccessStatus == null) {
+ logAccessStatus = new LogAccessStatus();
+ mLogAccessStatus.put(client, logAccessStatus);
+ }
+
+ switch (logAccessStatus.mStatus) {
+ case STATUS_NEW_REQUEST:
+ logAccessStatus.mPendingRequests.add(request);
+ processNewLogAccessRequest(client);
+ break;
+ case STATUS_PENDING:
+ logAccessStatus.mPendingRequests.add(request);
+ return;
+ case STATUS_APPROVED:
+ approveRequest(client, request);
+ break;
+ case STATUS_DECLINED:
+ declineRequest(request);
+ break;
+ }
+ }
+
+ private boolean shouldShowConfirmationDialog(LogAccessClient client) {
+ // If the process is foreground, show a dialog for user consent
+ final int procState = mActivityManagerInternal.getUidProcessState(client.mUid);
+ return procState == ActivityManager.PROCESS_STATE_TOP;
+ }
+
+ private void processNewLogAccessRequest(LogAccessClient client) {
+ boolean isInstrumented = mActivityManagerInternal.isUidCurrentlyInstrumented(client.mUid);
+
+ // The instrumented apks only run for testing, so we don't check user permission.
+ if (isInstrumented) {
+ onAccessApprovedForClient(client);
+ return;
+ }
+
+ if (!shouldShowConfirmationDialog(client)) {
+ onAccessDeclinedForClient(client);
+ return;
+ }
+
+ final LogAccessStatus logAccessStatus = mLogAccessStatus.get(client);
+ logAccessStatus.mStatus = STATUS_PENDING;
+
+ mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_PENDING_TIMEOUT, client),
+ mClock.get() + PENDING_CONFIRMATION_TIMEOUT_MILLIS);
+ final Intent mIntent = createIntent(client);
+ mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
+ }
+
+ void onAccessApprovedForClient(LogAccessClient client) {
+ scheduleStatusExpiry(client);
+
+ LogAccessStatus logAccessStatus = mLogAccessStatus.get(client);
+ if (logAccessStatus != null) {
+ for (LogAccessRequest request : logAccessStatus.mPendingRequests) {
+ approveRequest(client, request);
+ }
+ logAccessStatus.mStatus = STATUS_APPROVED;
+ logAccessStatus.mPendingRequests.clear();
+ }
+ }
+
+ void onAccessDeclinedForClient(LogAccessClient client) {
+ scheduleStatusExpiry(client);
+
+ LogAccessStatus logAccessStatus = mLogAccessStatus.get(client);
+ if (logAccessStatus != null) {
+ for (LogAccessRequest request : logAccessStatus.mPendingRequests) {
+ declineRequest(request);
+ }
+ logAccessStatus.mStatus = STATUS_DECLINED;
+ logAccessStatus.mPendingRequests.clear();
+ }
+ }
+
+ private void scheduleStatusExpiry(LogAccessClient client) {
+ mHandler.removeMessages(MSG_PENDING_TIMEOUT, client);
+ mHandler.removeMessages(MSG_LOG_ACCESS_STATUS_EXPIRED, client);
+ mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_LOG_ACCESS_STATUS_EXPIRED, client),
+ mClock.get() + STATUS_EXPIRATION_TIMEOUT_MILLIS);
+ }
+
+ void onPendingTimeoutExpired(LogAccessClient client) {
+ final LogAccessStatus logAccessStatus = mLogAccessStatus.get(client);
+ if (logAccessStatus != null && logAccessStatus.mStatus == STATUS_PENDING) {
+ onAccessDeclinedForClient(client);
+ }
+ }
+
+ void onAccessStatusExpired(LogAccessClient client) {
+ if (DEBUG) {
+ Slog.d(TAG, "Log access status expired for " + client);
+ }
+ mLogAccessStatus.remove(client);
+ }
+
+ void onLogAccessFinished(LogAccessRequest request) {
+ final LogAccessClient client = getClientForRequest(request);
+ final int activeCount = mActiveLogAccessCount.getOrDefault(client, 1) - 1;
+
+ if (activeCount == 0) {
+ mActiveLogAccessCount.remove(client);
+ if (DEBUG) {
+ Slog.d(TAG, "Client is no longer accessing logs: " + client);
+ }
+ // TODO This will be used to notify the AppOpsManager that the logd data access
+ // is finished.
+ } else {
+ mActiveLogAccessCount.put(client, activeCount);
+ }
+ }
+
+ private void approveRequest(LogAccessClient client, LogAccessRequest request) {
+ if (DEBUG) {
+ Slog.d(TAG, "Approving log access: " + request);
+ }
try {
- getLogdService().decline(uid, gid, pid, fd);
+ getLogdService().approve(request.mUid, request.mGid, request.mPid, request.mFd);
+ Integer activeCount = mActiveLogAccessCount.getOrDefault(client, 0);
+ mActiveLogAccessCount.put(client, activeCount + 1);
} catch (RemoteException e) {
Slog.e(TAG, "Fails to call remote functions", e);
}
}
- private static String getClientInfo(int uid, int gid, int pid, int fd) {
- return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID="
- + Integer.toString(pid) + " FD=" + Integer.toString(fd);
- }
-
- private class LogdMonitor implements Runnable {
-
- private final int mUid;
- private final int mGid;
- private final int mPid;
- private final int mFd;
- private final boolean mStart;
-
- /**
- * For starting a thread, the start value is true.
- * For finishing a thread, the start value is false.
- */
- LogdMonitor(int uid, int gid, int pid, int fd, boolean start) {
- mUid = uid;
- mGid = gid;
- mPid = pid;
- mFd = fd;
- mStart = start;
+ private void declineRequest(LogAccessRequest request) {
+ if (DEBUG) {
+ Slog.d(TAG, "Declining log access: " + request);
}
-
- /**
- * LogdMonitor generates a prompt for users.
- * The users decide whether the logd access is allowed.
- */
- @Override
- public void run() {
- if (mLogdService == null) {
- LogcatManagerService.this.addLogdService();
- }
-
- if (mStart) {
-
- ActivityManagerInternal ami = LocalServices.getService(
- ActivityManagerInternal.class);
- boolean isCallerInstrumented = ami.isUidCurrentlyInstrumented(mUid);
-
- // The instrumented apks only run for testing, so we don't check user permission.
- if (isCallerInstrumented) {
- try {
- getLogdService().approve(mUid, mGid, mPid, mFd);
- } catch (RemoteException e) {
- Slog.e(TAG, "Fails to call remote functions", e);
- }
- return;
- }
-
- final int procState = LocalServices.getService(ActivityManagerInternal.class)
- .getUidProcessState(mUid);
- // If the process is foreground and we can retrieve the package name, show a dialog
- // for user consent
- if (procState == ActivityManager.PROCESS_STATE_TOP) {
- String packageName = getPackageName(mUid, mGid, mPid, mFd);
- if (packageName != null) {
- final Intent mIntent = createIntent(packageName, mUid, mGid, mPid, mFd);
- mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
- return;
- }
- }
-
- /**
- * If the process is background or cannot retrieve the package name,
- * decline the logd access.
- **/
- declineLogdAccess(mUid, mGid, mPid, mFd);
- return;
- }
- }
- }
-
- public LogcatManagerService(Context context) {
- super(context);
- mContext = context;
- mBinderService = new BinderService();
- mThreadExecutor = Executors.newCachedThreadPool();
- mActivityManager = context.getSystemService(ActivityManager.class);
- }
-
- @Override
- public void onStart() {
try {
- publishBinderService("logcat", mBinderService);
- } catch (Throwable t) {
- Slog.e(TAG, "Could not start the LogcatManagerService.", t);
+ getLogdService().decline(request.mUid, request.mGid, request.mPid, request.mFd);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Fails to call remote functions", e);
}
}
- private void addLogdService() {
- mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd"));
- }
-
/**
* Create the Intent for LogAccessDialogActivity.
*/
- public Intent createIntent(String targetPackageName, int uid, int gid, int pid, int fd) {
- final Intent intent = new Intent();
+ public Intent createIntent(LogAccessClient client) {
+ final Intent intent = new Intent(mContext, LogAccessDialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName);
- intent.putExtra(EXTRA_UID, uid);
- intent.putExtra(EXTRA_GID, gid);
- intent.putExtra(EXTRA_PID, pid);
- intent.putExtra(EXTRA_FD, fd);
-
- intent.setComponent(new ComponentName(TARGET_PACKAGE_NAME, TARGET_ACTIVITY_NAME));
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, client.mPackageName);
+ intent.putExtra(Intent.EXTRA_UID, client.mUid);
return intent;
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 92703ec..604e8f3 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -60,8 +60,8 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.NoSuchElementException;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* This is the system implementation of a Session. Apps will interact with the
@@ -1159,6 +1159,9 @@
public void sendCommand(String packageName, int pid, int uid, String command, Bundle args,
ResultReceiver cb) {
try {
+ final String reason = TAG + ":" + command;
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onCommand(packageName, pid, uid, command, args, cb);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in sendCommand.", e);
@@ -1168,6 +1171,9 @@
public void sendCustomAction(String packageName, int pid, int uid, String action,
Bundle args) {
try {
+ final String reason = TAG + ":custom-" + action;
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onCustomAction(packageName, pid, uid, action, args);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in sendCustomAction.", e);
@@ -1176,6 +1182,9 @@
public void prepare(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":prepare";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPrepare(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in prepare.", e);
@@ -1185,6 +1194,9 @@
public void prepareFromMediaId(String packageName, int pid, int uid, String mediaId,
Bundle extras) {
try {
+ final String reason = TAG + ":prepareFromMediaId";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPrepareFromMediaId(packageName, pid, uid, mediaId, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in prepareFromMediaId.", e);
@@ -1194,6 +1206,9 @@
public void prepareFromSearch(String packageName, int pid, int uid, String query,
Bundle extras) {
try {
+ final String reason = TAG + ":prepareFromSearch";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPrepareFromSearch(packageName, pid, uid, query, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in prepareFromSearch.", e);
@@ -1202,6 +1217,9 @@
public void prepareFromUri(String packageName, int pid, int uid, Uri uri, Bundle extras) {
try {
+ final String reason = TAG + ":prepareFromUri";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPrepareFromUri(packageName, pid, uid, uri, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in prepareFromUri.", e);
@@ -1210,6 +1228,9 @@
public void play(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":play";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPlay(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in play.", e);
@@ -1219,6 +1240,9 @@
public void playFromMediaId(String packageName, int pid, int uid, String mediaId,
Bundle extras) {
try {
+ final String reason = TAG + ":playFromMediaId";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPlayFromMediaId(packageName, pid, uid, mediaId, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in playFromMediaId.", e);
@@ -1228,6 +1252,9 @@
public void playFromSearch(String packageName, int pid, int uid, String query,
Bundle extras) {
try {
+ final String reason = TAG + ":playFromSearch";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPlayFromSearch(packageName, pid, uid, query, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in playFromSearch.", e);
@@ -1236,6 +1263,9 @@
public void playFromUri(String packageName, int pid, int uid, Uri uri, Bundle extras) {
try {
+ final String reason = TAG + ":playFromUri";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPlayFromUri(packageName, pid, uid, uri, extras);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in playFromUri.", e);
@@ -1244,6 +1274,9 @@
public void skipToTrack(String packageName, int pid, int uid, long id) {
try {
+ final String reason = TAG + ":skipToTrack";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onSkipToTrack(packageName, pid, uid, id);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in skipToTrack", e);
@@ -1252,6 +1285,9 @@
public void pause(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":pause";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPause(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in pause.", e);
@@ -1260,6 +1296,9 @@
public void stop(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":stop";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onStop(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in stop.", e);
@@ -1268,6 +1307,9 @@
public void next(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":next";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onNext(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in next.", e);
@@ -1276,6 +1318,9 @@
public void previous(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":previous";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onPrevious(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in previous.", e);
@@ -1284,6 +1329,9 @@
public void fastForward(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":fastForward";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onFastForward(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in fastForward.", e);
@@ -1292,6 +1340,9 @@
public void rewind(String packageName, int pid, int uid) {
try {
+ final String reason = TAG + ":rewind";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onRewind(packageName, pid, uid);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in rewind.", e);
@@ -1300,6 +1351,9 @@
public void seekTo(String packageName, int pid, int uid, long pos) {
try {
+ final String reason = TAG + ":seekTo";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onSeekTo(packageName, pid, uid, pos);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in seekTo.", e);
@@ -1308,6 +1362,9 @@
public void rate(String packageName, int pid, int uid, Rating rating) {
try {
+ final String reason = TAG + ":rate";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onRate(packageName, pid, uid, rating);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in rate.", e);
@@ -1316,6 +1373,9 @@
public void setPlaybackSpeed(String packageName, int pid, int uid, float speed) {
try {
+ final String reason = TAG + ":setPlaybackSpeed";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onSetPlaybackSpeed(packageName, pid, uid, speed);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in setPlaybackSpeed.", e);
@@ -1325,6 +1385,9 @@
public void adjustVolume(String packageName, int pid, int uid, boolean asSystemService,
int direction) {
try {
+ final String reason = TAG + ":adjustVolume";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
if (asSystemService) {
mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(),
Process.SYSTEM_UID, direction);
@@ -1338,6 +1401,9 @@
public void setVolumeTo(String packageName, int pid, int uid, int value) {
try {
+ final String reason = TAG + ":setVolumeTo";
+ mService.tempAllowlistTargetPkgIfPossible(getUid(), getPackageName(),
+ pid, uid, packageName, reason);
mCb.onSetVolumeTo(packageName, pid, uid, value);
} catch (RemoteException e) {
Log.e(TAG, "Remote failure in setVolumeTo.", e);
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 02f9ceb..89902f7 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -51,14 +51,16 @@
void onNotificationSettingsViewed(String key);
/**
* Called when the state of {@link Notification#FLAG_BUBBLE} is changed.
+ *
+ * @param key the notification key
+ * @param isBubble whether the notification should have {@link Notification#FLAG_BUBBLE} applied
+ * @param flags the flags to apply to the notification's {@link Notification.BubbleMetadata}
*/
void onNotificationBubbleChanged(String key, boolean isBubble, int flags);
/**
- * Called when the state of {@link Notification.BubbleMetadata#FLAG_SUPPRESS_NOTIFICATION}
- * or {@link Notification.BubbleMetadata#FLAG_SUPPRESS_BUBBLE} changes.
+ * Called when the flags on {@link Notification.BubbleMetadata} are changed.
*/
- void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed,
- boolean isBubbleSuppressed);
+ void onBubbleMetadataFlagChanged(String key, int flags);
/**
* Grant permission to read the specified URI to the package associated with the
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index c548e7e..8a62736 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -42,4 +42,7 @@
/** Does the specified package/uid have permission to post notifications? */
boolean areNotificationsEnabledForPackage(String pkg, int uid);
+
+ /** Send a notification to the user prompting them to review their notification permissions. */
+ void sendReviewPermissionsNotification();
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6078bfc..9042326 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -18,6 +18,7 @@
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
@@ -57,6 +58,7 @@
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_NOT_PERCEPTIBLE;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
@@ -274,6 +276,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
@@ -442,6 +445,18 @@
private static final int NOTIFICATION_INSTANCE_ID_MAX = (1 << 13);
+ // States for the review permissions notification
+ static final int REVIEW_NOTIF_STATE_UNKNOWN = -1;
+ static final int REVIEW_NOTIF_STATE_SHOULD_SHOW = 0;
+ static final int REVIEW_NOTIF_STATE_USER_INTERACTED = 1;
+ static final int REVIEW_NOTIF_STATE_DISMISSED = 2;
+ static final int REVIEW_NOTIF_STATE_RESHOWN = 3;
+
+ // Action strings for review permissions notification
+ static final String REVIEW_NOTIF_ACTION_REMIND = "REVIEW_NOTIF_ACTION_REMIND";
+ static final String REVIEW_NOTIF_ACTION_DISMISS = "REVIEW_NOTIF_ACTION_DISMISS";
+ static final String REVIEW_NOTIF_ACTION_CANCELED = "REVIEW_NOTIF_ACTION_CANCELED";
+
/**
* Apps that post custom toasts in the background will have those blocked. Apps can
* still post toasts created with
@@ -641,10 +656,10 @@
private int mWarnRemoteViewsSizeBytes;
private int mStripRemoteViewsSizeBytes;
- final boolean mEnableAppSettingMigration;
private boolean mForceUserSetOnUpgrade;
private MetricsLogger mMetricsLogger;
+ private NotificationChannelLogger mNotificationChannelLogger;
private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable();
@@ -652,6 +667,9 @@
private InstanceIdSequence mNotificationInstanceIdSequence;
private Set<String> mMsgPkgsAllowedAsConvos = new HashSet();
+ // Broadcast intent receiver for notification permissions review-related intents
+ private ReviewNotificationPermissionsReceiver mReviewNotificationPermissionsReceiver;
+
static class Archive {
final SparseArray<Boolean> mEnabled;
final int mBufferSize;
@@ -1413,8 +1431,7 @@
}
@Override
- public void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed,
- boolean isBubbleSuppressed) {
+ public void onBubbleMetadataFlagChanged(String key, int flags) {
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r != null) {
@@ -1424,17 +1441,12 @@
return;
}
- boolean flagChanged = false;
- if (data.isNotificationSuppressed() != isNotifSuppressed) {
- flagChanged = true;
- data.setSuppressNotification(isNotifSuppressed);
- }
- if (data.isBubbleSuppressed() != isBubbleSuppressed) {
- flagChanged = true;
- data.setSuppressBubble(isBubbleSuppressed);
- }
- if (flagChanged) {
+ if (flags != data.getFlags()) {
+ data.setFlags(flags);
+ // Shouldn't alert again just because of a flag change.
r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
+ // Force isAppForeground true here, because for sysui's purposes we
+ // want to be able to adjust the flag behaviour.
mHandler.post(
new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
true /* isAppForeground */, SystemClock.elapsedRealtime()));
@@ -1987,12 +1999,6 @@
mNotificationRecordLogger = notificationRecordLogger;
mNotificationInstanceIdSequence = notificationInstanceIdSequence;
Notification.processAllowlistToken = ALLOWLIST_TOKEN;
- // TODO (b/194833441): remove when OS is ready for migration. This flag is checked once
- // rather than having a settings observer because some of the behaviors (e.g. readXml) only
- // happen on reboot
- mEnableAppSettingMigration = Settings.Secure.getIntForUser(
- getContext().getContentResolver(),
- Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM) == 1;
}
// TODO - replace these methods with new fields in the VisibleForTesting constructor
@@ -2150,6 +2156,11 @@
mAccessibilityManager = am;
}
+ @VisibleForTesting
+ void setTelecomManager(TelecomManager tm) {
+ mTelecomManager = tm;
+ }
+
// TODO: All tests should use this init instead of the one-off setters above.
@VisibleForTesting
void init(WorkerHandler handler, RankingHandler rankingHandler,
@@ -2167,7 +2178,7 @@
TelephonyManager telephonyManager, ActivityManagerInternal ami,
MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper,
UsageStatsManagerInternal usageStatsManagerInternal,
- TelecomManager telecomManager) {
+ TelecomManager telecomManager, NotificationChannelLogger channelLogger) {
mHandler = handler;
Resources resources = getContext().getResources();
mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
@@ -2264,12 +2275,13 @@
}
});
mPermissionHelper = permissionHelper;
+ mNotificationChannelLogger = channelLogger;
mPreferencesHelper = new PreferencesHelper(getContext(),
mPackageManagerClient,
mRankingHandler,
mZenModeHelper,
mPermissionHelper,
- new NotificationChannelLoggerImpl(),
+ mNotificationChannelLogger,
mAppOps,
new SysUiStatsEvent.BuilderFactory());
mRankingHelper = new RankingHelper(getContext(),
@@ -2351,9 +2363,6 @@
mNotificationEffectsEnabledForAutomotive =
resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive);
- mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray(
- com.android.internal.R.array.config_nonBlockableNotificationPackages));
-
mZenModeHelper.setPriorityOnlyDndExemptPackages(getContext().getResources().getStringArray(
com.android.internal.R.array.config_priorityOnlyDndExemptPackages));
@@ -2416,6 +2425,11 @@
IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
getContext().registerReceiver(mLocaleChangeReceiver, localeChangedFilter);
+
+ mReviewNotificationPermissionsReceiver = new ReviewNotificationPermissionsReceiver();
+ getContext().registerReceiver(mReviewNotificationPermissionsReceiver,
+ ReviewNotificationPermissionsReceiver.getFilter(),
+ Context.RECEIVER_NOT_EXPORTED);
}
/**
@@ -2488,10 +2502,11 @@
LocalServices.getService(ActivityManagerInternal.class),
createToastRateLimiter(), new PermissionHelper(LocalServices.getService(
PermissionManagerServiceInternal.class), AppGlobals.getPackageManager(),
- AppGlobals.getPermissionManager(), mEnableAppSettingMigration,
+ AppGlobals.getPermissionManager(),
mForceUserSetOnUpgrade),
LocalServices.getService(UsageStatsManagerInternal.class),
- getContext().getSystemService(TelecomManager.class));
+ getContext().getSystemService(TelecomManager.class),
+ new NotificationChannelLoggerImpl());
publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -2709,6 +2724,7 @@
mHistoryManager.onBootPhaseAppsCanStart();
registerDeviceConfigChange();
migrateDefaultNAS();
+ maybeShowInitialReviewPermissionsNotification();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mSnoozeHelper.scheduleRepostsForPersistedNotifications(System.currentTimeMillis());
}
@@ -2782,7 +2798,7 @@
}
}
- private void updateNotificationChannelInt(String pkg, int uid, NotificationChannel channel,
+ void updateNotificationChannelInt(String pkg, int uid, NotificationChannel channel,
boolean fromListener) {
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
// cancel
@@ -2804,11 +2820,9 @@
mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), true);
mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true);
- if (mEnableAppSettingMigration) {
- if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) {
- mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid),
- channel.getImportance() != IMPORTANCE_NONE, true);
- }
+ if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) {
+ mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid),
+ channel.getImportance() != IMPORTANCE_NONE, true);
}
maybeNotifyChannelOwner(pkg, uid, preUpdate, channel);
@@ -3457,36 +3471,19 @@
@Override
public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
enforceSystemOrSystemUI("setNotificationsEnabledForPackage");
- if (mEnableAppSettingMigration) {
- boolean wasEnabled = mPermissionHelper.hasPermission(uid);
- if (wasEnabled == enabled) {
- return;
- }
- mPermissionHelper.setNotificationPermission(
- pkg, UserHandle.getUserId(uid), enabled, true);
- sendAppBlockStateChangedBroadcast(pkg, uid, !enabled);
- } else {
- synchronized (mNotificationLock) {
- boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid)
- != NotificationManager.IMPORTANCE_NONE;
-
- if (wasEnabled == enabled) {
- return;
- }
- }
-
- mPreferencesHelper.setEnabled(pkg, uid, enabled);
- // TODO (b/194833441): this is being ignored by app ops now that the permission
- // exists, so send the broadcast manually
- mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
- enabled ? MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
-
- sendAppBlockStateChangedBroadcast(pkg, uid, !enabled);
+ boolean wasEnabled = mPermissionHelper.hasPermission(uid);
+ if (wasEnabled == enabled) {
+ return;
}
+ mPermissionHelper.setNotificationPermission(
+ pkg, UserHandle.getUserId(uid), enabled, true);
+ sendAppBlockStateChangedBroadcast(pkg, uid, !enabled);
+
mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES)
.setType(MetricsEvent.TYPE_ACTION)
.setPackageName(pkg)
.setSubtype(enabled ? 1 : 0));
+ mNotificationChannelLogger.logAppNotificationsAllowed(uid, pkg, enabled);
// Now, cancel any outstanding notifications that are part of a just-disabled app
if (!enabled) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, null, 0, 0, true,
@@ -3512,8 +3509,6 @@
public void setNotificationsEnabledWithImportanceLockForPackage(
String pkg, int uid, boolean enabled) {
setNotificationsEnabledForPackage(pkg, uid, enabled);
-
- mPreferencesHelper.setAppImportanceLocked(pkg, uid);
}
/**
@@ -3629,14 +3624,10 @@
@Override
public int getPackageImportance(String pkg) {
checkCallerIsSystemOrSameApp(pkg);
- if (mEnableAppSettingMigration) {
- if (mPermissionHelper.hasPermission(Binder.getCallingUid())) {
- return IMPORTANCE_DEFAULT;
- } else {
- return IMPORTANCE_NONE;
- }
+ if (mPermissionHelper.hasPermission(Binder.getCallingUid())) {
+ return IMPORTANCE_DEFAULT;
} else {
- return mPreferencesHelper.getImportance(pkg, Binder.getCallingUid());
+ return IMPORTANCE_NONE;
}
}
@@ -5868,8 +5859,7 @@
NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey,
boolean needsOngoingFlag) {
NotificationRecord summaryRecord = null;
- boolean isPermissionFixed = mPermissionHelper.isMigrationEnabled()
- ? mPermissionHelper.isPermissionFixed(pkg, userId) : false;
+ boolean isPermissionFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
synchronized (mNotificationLock) {
NotificationRecord notificationRecord = mNotificationsByKey.get(triggeringKey);
if (notificationRecord == null) {
@@ -5878,10 +5868,6 @@
return null;
}
NotificationChannel channel = notificationRecord.getChannel();
- boolean isImportanceFixed = mPermissionHelper.isMigrationEnabled()
- ? isPermissionFixed
- : (channel.isImportanceLockedByOEM()
- || channel.isImportanceLockedByCriticalDeviceFunction());
final StatusBarNotification adjustedSbn = notificationRecord.getSbn();
userId = adjustedSbn.getUser().getIdentifier();
int uid = adjustedSbn.getUid();
@@ -5927,7 +5913,7 @@
System.currentTimeMillis());
summaryRecord = new NotificationRecord(getContext(), summarySbn,
notificationRecord.getChannel());
- summaryRecord.setImportanceFixed(isImportanceFixed);
+ summaryRecord.setImportanceFixed(isPermissionFixed);
summaryRecord.setIsAppImportanceLocked(
notificationRecord.getIsAppImportanceLocked());
summaries.put(pkg, summarySbn.getKey());
@@ -5975,10 +5961,6 @@
@VisibleForTesting
protected ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>>
getAllUsersNotificationPermissions() {
- // don't bother if migration is not enabled
- if (!mEnableAppSettingMigration) {
- return null;
- }
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> allPermissions = new ArrayMap<>();
final List<UserInfo> allUsers = mUm.getUsers();
// for each of these, get the package notification permissions that are associated
@@ -6336,6 +6318,21 @@
public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
return areNotificationsEnabledForPackageInt(pkg, uid);
}
+
+ @Override
+ public void sendReviewPermissionsNotification() {
+ // This method is meant to be called from the JobService upon running the job for this
+ // notification having been rescheduled; so without checking any other state, it will
+ // send the notification.
+ checkCallerIsSystem();
+ NotificationManager nm = getContext().getSystemService(NotificationManager.class);
+ nm.notify(TAG,
+ SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS,
+ createReviewPermissionsNotification());
+ Settings.Global.putInt(getContext().getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
+ }
};
int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) {
@@ -6477,13 +6474,8 @@
+ ", notificationUid=" + notificationUid
+ ", notification=" + notification;
Slog.e(TAG, noChannelStr);
- boolean appNotificationsOff;
- if (mEnableAppSettingMigration) {
- appNotificationsOff = !mPermissionHelper.hasPermission(notificationUid);
- } else {
- appNotificationsOff = mPreferencesHelper.getImportance(pkg, notificationUid)
- == NotificationManager.IMPORTANCE_NONE;
- }
+ boolean appNotificationsOff = !mPermissionHelper.hasPermission(notificationUid);
+
if (!appNotificationsOff) {
doChannelWarningToast(notificationUid,
@@ -6495,14 +6487,11 @@
}
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
- r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
+ r.setIsAppImportanceLocked(mPermissionHelper.isPermissionUserSet(pkg, userId));
r.setPostSilently(postSilently);
r.setFlagBubbleRemoved(false);
r.setPkgAllowedAsConvo(mMsgPkgsAllowedAsConvos.contains(pkg));
- boolean isImportanceFixed = mPermissionHelper.isMigrationEnabled()
- ? mPermissionHelper.isPermissionFixed(pkg, userId)
- : (channel.isImportanceLockedByOEM()
- || channel.isImportanceLockedByCriticalDeviceFunction());
+ boolean isImportanceFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
r.setImportanceFixed(isImportanceFixed);
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
@@ -6946,19 +6935,20 @@
private boolean isCallNotification(String pkg, int uid) {
final long identity = Binder.clearCallingIdentity();
try {
- return mTelecomManager.isInManagedCall() || mTelecomManager.isInSelfManagedCall(
- pkg, UserHandle.getUserHandleForUid(uid));
+ if (mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)
+ && mTelecomManager != null) {
+ return mTelecomManager.isInManagedCall()
+ || mTelecomManager.isInSelfManagedCall(
+ pkg, UserHandle.getUserHandleForUid(uid));
+ }
+ return false;
} finally {
Binder.restoreCallingIdentity(identity);
}
}
private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) {
- if (mEnableAppSettingMigration) {
- return mPermissionHelper.hasPermission(uid);
- } else {
- return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
- }
+ return mPermissionHelper.hasPermission(uid);
}
protected int getNotificationCount(String pkg, int userId, int excludedId,
@@ -7145,10 +7135,12 @@
&& r.getNotification().isBubbleNotification())
|| (mReason == REASON_CLICK && r.canBubble()
&& r.isFlagBubbleRemoved())) {
- boolean isBubbleSuppressed = r.getNotification().getBubbleMetadata() != null
- && r.getNotification().getBubbleMetadata().isBubbleSuppressed();
- mNotificationDelegate.onBubbleNotificationSuppressionChanged(
- r.getKey(), true /* notifSuppressed */, isBubbleSuppressed);
+ int flags = 0;
+ if (r.getNotification().getBubbleMetadata() != null) {
+ flags = r.getNotification().getBubbleMetadata().getFlags();
+ }
+ flags |= FLAG_SUPPRESS_NOTIFICATION;
+ mNotificationDelegate.onBubbleMetadataFlagChanged(r.getKey(), flags);
return;
}
if ((r.getNotification().flags & mMustHaveFlags) != mMustHaveFlags) {
@@ -7371,6 +7363,7 @@
@Override
public void run() {
boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
+ boolean isCallNotification = isCallNotification(pkg, uid);
synchronized (mNotificationLock) {
try {
NotificationRecord r = null;
@@ -7389,8 +7382,10 @@
final StatusBarNotification n = r.getSbn();
final Notification notification = n.getNotification();
+ boolean isCallNotificationAndCorrectStyle = isCallNotification
+ && notification.isStyle(Notification.CallStyle.class);
- if (!notification.isMediaNotification()
+ if (!(notification.isMediaNotification() || isCallNotificationAndCorrectStyle)
&& (appBanned || isRecordBlockedLocked(r))) {
mUsageStats.registerBlocked(r);
if (DBG) {
@@ -11608,6 +11603,76 @@
out.endTag(null, LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_TAG);
}
+ // Creates a notification that informs the user about changes due to the migration to
+ // use permissions for notifications.
+ protected Notification createReviewPermissionsNotification() {
+ int title = R.string.review_notification_settings_title;
+ int content = R.string.review_notification_settings_text;
+
+ // Tapping on the notification leads to the settings screen for managing app notifications,
+ // using the intent reserved for system services to indicate it comes from this notification
+ Intent tapIntent = new Intent(Settings.ACTION_ALL_APPS_NOTIFICATION_SETTINGS_FOR_REVIEW);
+ Intent remindIntent = new Intent(REVIEW_NOTIF_ACTION_REMIND);
+ Intent dismissIntent = new Intent(REVIEW_NOTIF_ACTION_DISMISS);
+ Intent swipeIntent = new Intent(REVIEW_NOTIF_ACTION_CANCELED);
+
+ // Both "remind me" and "dismiss" actions will be actions received by the BroadcastReceiver
+ final Notification.Action remindMe = new Notification.Action.Builder(null,
+ getContext().getResources().getString(
+ R.string.review_notification_settings_remind_me_action),
+ PendingIntent.getBroadcast(
+ getContext(), 0, remindIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .build();
+ final Notification.Action dismiss = new Notification.Action.Builder(null,
+ getContext().getResources().getString(
+ R.string.review_notification_settings_dismiss),
+ PendingIntent.getBroadcast(
+ getContext(), 0, dismissIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .build();
+
+ return new Notification.Builder(getContext(), SystemNotificationChannels.SYSTEM_CHANGES)
+ .setSmallIcon(R.drawable.stat_sys_adb)
+ .setContentTitle(getContext().getResources().getString(title))
+ .setContentText(getContext().getResources().getString(content))
+ .setContentIntent(PendingIntent.getActivity(getContext(), 0, tapIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .setStyle(new Notification.BigTextStyle())
+ .setFlag(Notification.FLAG_NO_CLEAR, true)
+ .setAutoCancel(true)
+ .addAction(remindMe)
+ .addAction(dismiss)
+ .setDeleteIntent(PendingIntent.getBroadcast(getContext(), 0, swipeIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .build();
+ }
+
+ protected void maybeShowInitialReviewPermissionsNotification() {
+ int currentState = Settings.Global.getInt(getContext().getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ REVIEW_NOTIF_STATE_UNKNOWN);
+
+ // now check the last known state of the notification -- this determination of whether the
+ // user is in the correct target audience occurs elsewhere, and will have written the
+ // REVIEW_NOTIF_STATE_SHOULD_SHOW to indicate it should be shown in the future.
+ //
+ // alternatively, if the user has rescheduled the notification (so it has been shown
+ // again) but not yet interacted with the new notification, then show it again on boot,
+ // as this state indicates that the user had the notification open before rebooting.
+ //
+ // sending the notification here does not record a new state for the notification;
+ // that will be written by parts of the system further down the line if at any point
+ // the user interacts with the notification.
+ if (currentState == REVIEW_NOTIF_STATE_SHOULD_SHOW
+ || currentState == REVIEW_NOTIF_STATE_RESHOWN) {
+ NotificationManager nm = getContext().getSystemService(NotificationManager.class);
+ nm.notify(TAG,
+ SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS,
+ createReviewPermissionsNotification());
+ }
+ }
+
/**
* Shows a warning on logcat. Shows the toast only once per package. This is to avoid being too
* aggressive and annoying the user.
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index f979343..cbaf485 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -1089,7 +1089,7 @@
}
/**
- * @see PreferencesHelper#getIsAppImportanceLocked(String, int)
+ * @see PermissionHelper#isPermissionUserSet(String, int)
*/
public boolean getIsAppImportanceLocked() {
return mIsAppImportanceLocked;
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index a09aa7c..b2fee1e 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -55,31 +55,14 @@
private final PermissionManagerServiceInternal mPmi;
private final IPackageManager mPackageManager;
private final IPermissionManager mPermManager;
- // TODO (b/194833441): Remove this boolean (but keep the isMigrationEnabled() method)
- // when the migration is enabled
- private final boolean mMigrationEnabled;
- private final boolean mIsTv;
private final boolean mForceUserSetOnUpgrade;
public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager,
- IPermissionManager permManager, boolean migrationEnabled,
- boolean forceUserSetOnUpgrade) {
+ IPermissionManager permManager, boolean forceUserSetOnUpgrade) {
mPmi = pmi;
mPackageManager = packageManager;
mPermManager = permManager;
- mMigrationEnabled = migrationEnabled;
mForceUserSetOnUpgrade = forceUserSetOnUpgrade;
- boolean isTv;
- try {
- isTv = mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0);
- } catch (RemoteException e) {
- isTv = false;
- }
- mIsTv = isTv;
- }
-
- public boolean isMigrationEnabled() {
- return mMigrationEnabled && !mIsTv;
}
/**
@@ -87,7 +70,6 @@
* with a lock held.
*/
public boolean hasPermission(int uid) {
- assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
return mPmi.checkPostNotificationsPermissionGrantedOrLegacyAccess(uid)
@@ -102,7 +84,6 @@
* Must not be called with a lock held. Format: uid, packageName
*/
Set<Pair<Integer, String>> getAppsRequestingPermission(int userId) {
- assertFlag();
Set<Pair<Integer, String>> requested = new HashSet<>();
List<PackageInfo> pkgs = getInstalledPackages(userId);
for (PackageInfo pi : pkgs) {
@@ -140,7 +121,6 @@
* with a lock held. Format: uid, packageName.
*/
Set<Pair<Integer, String>> getAppsGrantedPermission(int userId) {
- assertFlag();
Set<Pair<Integer, String>> granted = new HashSet<>();
ParceledListSlice<PackageInfo> parceledList = null;
try {
@@ -162,7 +142,6 @@
public @NonNull
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>>
getNotificationPermissionValues(int userId) {
- assertFlag();
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>();
Set<Pair<Integer, String>> allRequestingUids = getAppsRequestingPermission(userId);
Set<Pair<Integer, String>> allApprovedUids = getAppsGrantedPermission(userId);
@@ -189,7 +168,6 @@
*/
public void setNotificationPermission(String packageName, @UserIdInt int userId, boolean grant,
boolean userSet, boolean reviewRequired) {
- assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
// Do not change the permission if the package doesn't request it, do not change fixed
@@ -230,7 +208,6 @@
* restoring a pre-T backup on a T+ device
*/
public void setNotificationPermission(PackagePermission pkgPerm) {
- assertFlag();
if (pkgPerm == null || pkgPerm.packageName == null) {
return;
}
@@ -242,7 +219,6 @@
}
public boolean isPermissionFixed(String packageName, @UserIdInt int userId) {
- assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
try {
@@ -260,7 +236,6 @@
}
boolean isPermissionUserSet(String packageName, @UserIdInt int userId) {
- assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
try {
@@ -278,7 +253,6 @@
}
boolean isPermissionGrantedByDefaultOrRole(String packageName, @UserIdInt int userId) {
- assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
try {
@@ -297,7 +271,6 @@
private boolean packageRequestsNotificationPermission(String packageName,
@UserIdInt int userId) {
- assertFlag();
try {
String[] permissions = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS,
userId).requestedPermissions;
@@ -308,12 +281,6 @@
return false;
}
- private void assertFlag() {
- if (!mMigrationEnabled) {
- throw new IllegalStateException("Method called without checking flag value");
- }
- }
-
public static class PackagePermission {
public final String packageName;
public final @UserIdInt int userId;
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 0525b1e..4e3fbaa 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -96,6 +96,10 @@
private final int XML_VERSION;
/** What version to check to do the upgrade for bubbles. */
private static final int XML_VERSION_BUBBLES_UPGRADE = 1;
+ /** The first xml version with notification permissions enabled. */
+ private static final int XML_VERSION_NOTIF_PERMISSION = 3;
+ /** The first xml version that notifies users to review their notification permissions */
+ private static final int XML_VERSION_REVIEW_PERMISSIONS_NOTIFICATION = 4;
@VisibleForTesting
static final int UNKNOWN_UID = UserHandle.USER_NULL;
private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
@@ -205,11 +209,7 @@
mAppOps = appOpsManager;
mStatsEventBuilderFactory = statsEventBuilderFactory;
- if (mPermissionHelper.isMigrationEnabled()) {
- XML_VERSION = 3;
- } else {
- XML_VERSION = 2;
- }
+ XML_VERSION = 4;
updateBadgingEnabled();
updateBubblesEnabled();
@@ -226,8 +226,15 @@
final int xmlVersion = parser.getAttributeInt(null, ATT_VERSION, -1);
boolean upgradeForBubbles = xmlVersion == XML_VERSION_BUBBLES_UPGRADE;
- boolean migrateToPermission =
- (xmlVersion < XML_VERSION) && mPermissionHelper.isMigrationEnabled();
+ boolean migrateToPermission = (xmlVersion < XML_VERSION_NOTIF_PERMISSION);
+ if (xmlVersion < XML_VERSION_REVIEW_PERMISSIONS_NOTIFICATION) {
+ // make a note that we should show the notification at some point.
+ // it shouldn't be possible for the user to already have seen it, as the XML version
+ // would be newer then.
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
+ }
ArrayList<PermissionHelper.PackagePermission> pkgPerms = new ArrayList<>();
synchronized (mPackagePreferences) {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -381,8 +388,6 @@
hasUserConfiguredSettings(r));
pkgPerms.add(pkgPerm);
}
- } else if (!mPermissionHelper.isMigrationEnabled()) {
- r.importance = appImportance;
}
} catch (Exception e) {
Slog.w(TAG, "Failed to restore pkg", e);
@@ -405,16 +410,8 @@
} else {
channel.populateFromXml(parser);
}
- if (!mPermissionHelper.isMigrationEnabled()) {
- channel.setImportanceLockedByCriticalDeviceFunction(
- r.defaultAppLockedImportance);
- channel.setImportanceLockedByOEM(r.oemLockedImportance);
- if (!channel.isImportanceLockedByOEM()) {
- if (r.oemLockedChannels.contains(channel.getId())) {
- channel.setImportanceLockedByOEM(true);
- }
- }
- }
+ channel.setImportanceLockedByCriticalDeviceFunction(
+ r.defaultAppLockedImportance);
if (isShortcutOk(channel) && isDeletionOk(channel)) {
r.channels.put(id, channel);
@@ -592,7 +589,7 @@
out.endTag(null, TAG_STATUS_ICONS);
}
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>();
- if (mPermissionHelper.isMigrationEnabled() && forBackup) {
+ if (forBackup) {
notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId);
}
@@ -724,28 +721,6 @@
}
}
- /**
- * Gets importance.
- */
- @Override
- public int getImportance(String packageName, int uid) {
- synchronized (mPackagePreferences) {
- return getOrCreatePackagePreferencesLocked(packageName, uid).importance;
- }
- }
-
- /**
- * Returns whether the importance of the corresponding notification is user-locked and shouldn't
- * be adjusted by an assistant (via means of a blocking helper, for example). For the channel
- * locking field, see {@link NotificationChannel#USER_LOCKED_IMPORTANCE}.
- */
- public boolean getIsAppImportanceLocked(String packageName, int uid) {
- synchronized (mPackagePreferences) {
- int userLockedFields = getOrCreatePackagePreferencesLocked(packageName, uid).lockedAppFields;
- return (userLockedFields & LockableAppFields.USER_LOCKED_IMPORTANCE) != 0;
- }
- }
-
@Override
public boolean canShowBadge(String packageName, int uid) {
synchronized (mPackagePreferences) {
@@ -1031,16 +1006,10 @@
: NotificationChannel.DEFAULT_ALLOW_BUBBLE);
}
clearLockedFieldsLocked(channel);
- if (!mPermissionHelper.isMigrationEnabled()) {
- channel.setImportanceLockedByOEM(r.oemLockedImportance);
- if (!channel.isImportanceLockedByOEM()) {
- if (r.oemLockedChannels.contains(channel.getId())) {
- channel.setImportanceLockedByOEM(true);
- }
- }
- channel.setImportanceLockedByCriticalDeviceFunction(
- r.defaultAppLockedImportance);
- }
+
+ channel.setImportanceLockedByCriticalDeviceFunction(
+ r.defaultAppLockedImportance);
+
if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
channel.setLockscreenVisibility(
NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
@@ -1121,33 +1090,15 @@
updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
}
- if (mPermissionHelper.isMigrationEnabled()) {
- if (mPermissionHelper.isPermissionFixed(r.pkg, UserHandle.getUserId(r.uid))
- && !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) {
- updatedChannel.setImportance(channel.getImportance());
- }
- } else {
- // no importance updates are allowed if OEM blocked it
- updatedChannel.setImportanceLockedByOEM(channel.isImportanceLockedByOEM());
- if (updatedChannel.isImportanceLockedByOEM()) {
- updatedChannel.setImportance(channel.getImportance());
- }
- updatedChannel.setImportanceLockedByCriticalDeviceFunction(
- r.defaultAppLockedImportance);
- if (updatedChannel.isImportanceLockedByCriticalDeviceFunction()
- && updatedChannel.getImportance() == IMPORTANCE_NONE) {
- updatedChannel.setImportance(channel.getImportance());
- }
+ if ((mPermissionHelper.isPermissionFixed(r.pkg, UserHandle.getUserId(r.uid))
+ || channel.isImportanceLockedByCriticalDeviceFunction())
+ && !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) {
+ updatedChannel.setImportance(channel.getImportance());
}
r.channels.put(updatedChannel.getId(), updatedChannel);
if (onlyHasDefaultChannel(pkg, uid)) {
- if (!mPermissionHelper.isMigrationEnabled()) {
- // copy settings to app level so they are inherited by new channels
- // when the app migrates
- r.importance = updatedChannel.getImportance();
- }
r.priority = updatedChannel.canBypassDnd()
? Notification.PRIORITY_MAX : Notification.PRIORITY_DEFAULT;
r.visibility = updatedChannel.getLockscreenVisibility();
@@ -1316,61 +1267,8 @@
mHideSilentStatusBarIcons = hide;
}
- public void lockChannelsForOEM(String[] appOrChannelList) {
- if (mPermissionHelper.isMigrationEnabled()) {
- return;
- }
- if (appOrChannelList == null) {
- return;
- }
- for (String appOrChannel : appOrChannelList) {
- if (!TextUtils.isEmpty(appOrChannel)) {
- String[] appSplit = appOrChannel.split(NON_BLOCKABLE_CHANNEL_DELIM);
- if (appSplit != null && appSplit.length > 0) {
- String appName = appSplit[0];
- String channelId = appSplit.length == 2 ? appSplit[1] : null;
-
- synchronized (mPackagePreferences) {
- boolean foundApp = false;
- for (PackagePreferences r : mPackagePreferences.values()) {
- if (r.pkg.equals(appName)) {
- foundApp = true;
- if (channelId == null) {
- // lock all channels for the app
- r.oemLockedImportance = true;
- for (NotificationChannel channel : r.channels.values()) {
- channel.setImportanceLockedByOEM(true);
- }
- } else {
- NotificationChannel channel = r.channels.get(channelId);
- if (channel != null) {
- channel.setImportanceLockedByOEM(true);
- }
- // Also store the locked channels on the record, so they aren't
- // temporarily lost when data is cleared on the package
- r.oemLockedChannels.add(channelId);
- }
- }
- }
- if (!foundApp) {
- List<String> channels =
- mOemLockedApps.getOrDefault(appName, new ArrayList<>());
- if (channelId != null) {
- channels.add(channelId);
- }
- mOemLockedApps.put(appName, channels);
- }
- }
- }
- }
- }
- }
-
public void updateDefaultApps(int userId, ArraySet<String> toRemove,
ArraySet<Pair<String, Integer>> toAdd) {
- if (mPermissionHelper.isMigrationEnabled()) {
- return;
- }
synchronized (mPackagePreferences) {
for (PackagePreferences p : mPackagePreferences.values()) {
if (userId == UserHandle.getUserId(p.uid)) {
@@ -1790,20 +1688,8 @@
}
for (int i = candidatePkgs.size() - 1; i >= 0; i--) {
Pair<String, Integer> app = candidatePkgs.valueAt(i);
- if (mPermissionHelper.isMigrationEnabled()) {
- if (!mPermissionHelper.hasPermission(app.second)) {
- candidatePkgs.removeAt(i);
- }
- } else {
- synchronized (mPackagePreferences) {
- PackagePreferences r = getPackagePreferencesLocked(app.first, app.second);
- if (r == null) {
- continue;
- }
- if (r.importance == IMPORTANCE_NONE) {
- candidatePkgs.removeAt(i);
- }
- }
+ if (!mPermissionHelper.hasPermission(app.second)) {
+ candidatePkgs.removeAt(i);
}
}
boolean haveBypassingApps = candidatePkgs.size() > 0;
@@ -1849,27 +1735,6 @@
}
/**
- * Sets importance.
- */
- @Override
- public void setImportance(String pkgName, int uid, int importance) {
- synchronized (mPackagePreferences) {
- getOrCreatePackagePreferencesLocked(pkgName, uid).importance = importance;
- }
- updateConfig();
- }
-
- public void setEnabled(String packageName, int uid, boolean enabled) {
- boolean wasEnabled = getImportance(packageName, uid) != IMPORTANCE_NONE;
- if (wasEnabled == enabled) {
- return;
- }
- setImportance(packageName, uid,
- enabled ? DEFAULT_IMPORTANCE : IMPORTANCE_NONE);
- mNotificationChannelLogger.logAppNotificationsAllowed(uid, packageName, enabled);
- }
-
- /**
* Sets whether any notifications from the app, represented by the given {@code pkgName} and
* {@code uid}, have their importance locked by the user. Locked notifications don't get
* considered for sentiment adjustments (and thus never show a blocking helper).
@@ -2043,23 +1908,15 @@
pw.print(" (");
pw.print(r.uid == UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid));
pw.print(')');
- if (!mPermissionHelper.isMigrationEnabled()) {
- if (r.importance != DEFAULT_IMPORTANCE) {
- pw.print(" importance=");
- pw.print(NotificationListenerService.Ranking.importanceToString(
- r.importance));
- }
- } else {
- Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
- if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
- pw.print(" importance=");
- pw.print(NotificationListenerService.Ranking.importanceToString(
- packagePermissions.get(key).first
- ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
- pw.print(" userSet=");
- pw.print(packagePermissions.get(key).second);
- pkgsWithPermissionsToHandle.remove(key);
- }
+ Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
+ if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
+ pw.print(" importance=");
+ pw.print(NotificationListenerService.Ranking.importanceToString(
+ packagePermissions.get(key).first
+ ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
+ pw.print(" userSet=");
+ pw.print(packagePermissions.get(key).second);
+ pkgsWithPermissionsToHandle.remove(key);
}
if (r.priority != DEFAULT_PRIORITY) {
pw.print(" priority=");
@@ -2099,7 +1956,7 @@
}
}
// Handle any remaining packages with permissions
- if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) {
+ if (pkgsWithPermissionsToHandle != null) {
for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) {
// p.first is the uid of this package; p.second is the package name
if (filter.matches(p.second)) {
@@ -2139,16 +1996,12 @@
proto.write(RankingHelperProto.RecordProto.PACKAGE, r.pkg);
proto.write(RankingHelperProto.RecordProto.UID, r.uid);
- if (mPermissionHelper.isMigrationEnabled()) {
- Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
- if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
- proto.write(RankingHelperProto.RecordProto.IMPORTANCE,
- packagePermissions.get(key).first
- ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
- pkgsWithPermissionsToHandle.remove(key);
- }
- } else {
- proto.write(RankingHelperProto.RecordProto.IMPORTANCE, r.importance);
+ Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
+ if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
+ proto.write(RankingHelperProto.RecordProto.IMPORTANCE,
+ packagePermissions.get(key).first
+ ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
+ pkgsWithPermissionsToHandle.remove(key);
}
proto.write(RankingHelperProto.RecordProto.PRIORITY, r.priority);
proto.write(RankingHelperProto.RecordProto.VISIBILITY, r.visibility);
@@ -2165,7 +2018,7 @@
}
}
- if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) {
+ if (pkgsWithPermissionsToHandle != null) {
for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) {
if (filter.matches(p.second)) {
fToken = proto.start(fieldId);
@@ -2205,25 +2058,22 @@
// collect whether this package's importance info was user-set for later, if needed
// before the migration is enabled, this will simply default to false in all cases.
boolean importanceIsUserSet = false;
- if (mPermissionHelper.isMigrationEnabled()) {
- // Even if this package's data is not present, we need to write something;
- // so default to IMPORTANCE_NONE, since if PM doesn't know about the package
- // for some reason, notifications are not allowed.
- int importance = IMPORTANCE_NONE;
- Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
- if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
- Pair<Boolean, Boolean> permissionPair = pkgPermissions.get(key);
- importance = permissionPair.first
- ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE;
- // cache the second value for writing later
- importanceIsUserSet = permissionPair.second;
+ // Even if this package's data is not present, we need to write something;
+ // so default to IMPORTANCE_NONE, since if PM doesn't know about the package
+ // for some reason, notifications are not allowed.
+ int importance = IMPORTANCE_NONE;
+ Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
+ if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
+ Pair<Boolean, Boolean> permissionPair = pkgPermissions.get(key);
+ importance = permissionPair.first
+ ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE;
+ // cache the second value for writing later
+ importanceIsUserSet = permissionPair.second;
- pkgsWithPermissionsToHandle.remove(key);
- }
- event.writeInt(importance);
- } else {
- event.writeInt(r.importance);
+ pkgsWithPermissionsToHandle.remove(key);
}
+ event.writeInt(importance);
+
event.writeInt(r.visibility);
event.writeInt(r.lockedAppFields);
event.writeBoolean(importanceIsUserSet); // optional bool user_set_importance = 5;
@@ -2232,7 +2082,7 @@
}
// handle remaining packages with PackageManager permissions but not local settings
- if (mPermissionHelper.isMigrationEnabled() && pkgPermissions != null) {
+ if (pkgPermissions != null) {
for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) {
if (pulledEvents > NOTIFICATION_PREFERENCES_PULL_LIMIT) {
break;
@@ -2345,22 +2195,14 @@
try {
PackagePreferences.put("userId", UserHandle.getUserId(r.uid));
PackagePreferences.put("packageName", r.pkg);
- if (mPermissionHelper.isMigrationEnabled()) {
- Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
- if (pkgPermissions != null
- && pkgsWithPermissionsToHandle.contains(key)) {
- PackagePreferences.put("importance",
- NotificationListenerService.Ranking.importanceToString(
- pkgPermissions.get(key).first
- ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
- pkgsWithPermissionsToHandle.remove(key);
- }
- } else {
- if (r.importance != DEFAULT_IMPORTANCE) {
- PackagePreferences.put("importance",
- NotificationListenerService.Ranking.importanceToString(
- r.importance));
- }
+ Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
+ if (pkgPermissions != null
+ && pkgsWithPermissionsToHandle.contains(key)) {
+ PackagePreferences.put("importance",
+ NotificationListenerService.Ranking.importanceToString(
+ pkgPermissions.get(key).first
+ ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
+ pkgsWithPermissionsToHandle.remove(key);
}
if (r.priority != DEFAULT_PRIORITY) {
PackagePreferences.put("priority",
@@ -2392,7 +2234,7 @@
}
// handle packages for which there are permissions but no local settings
- if (mPermissionHelper.isMigrationEnabled() && pkgsWithPermissionsToHandle != null) {
+ if (pkgsWithPermissionsToHandle != null) {
for (Pair<Integer, String> p : pkgsWithPermissionsToHandle) {
if (filter == null || filter.matches(p.second)) {
JSONObject PackagePreferences = new JSONObject();
@@ -2431,8 +2273,7 @@
public JSONArray dumpBansJson(NotificationManagerService.DumpFilter filter,
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
JSONArray bans = new JSONArray();
- Map<Integer, String> packageBans = mPermissionHelper.isMigrationEnabled()
- ? getPermissionBasedPackageBans(pkgPermissions) : getPackageBans();
+ Map<Integer, String> packageBans = getPermissionBasedPackageBans(pkgPermissions);
for (Map.Entry<Integer, String> ban : packageBans.entrySet()) {
final int userId = UserHandle.getUserId(ban.getKey());
final String packageName = ban.getValue();
@@ -2585,7 +2426,7 @@
synchronized (mPackagePreferences) {
mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
}
- if (mPermissionHelper.isMigrationEnabled() && r.migrateToPm) {
+ if (r.migrateToPm) {
try {
PackagePermission p = new PackagePermission(
r.pkg, UserHandle.getUserId(r.uid),
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 3982593..3e9d90c 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -24,8 +24,6 @@
public interface RankingConfig {
- void setImportance(String packageName, int uid, int importance);
- int getImportance(String packageName, int uid);
void setShowBadge(String packageName, int uid, boolean showBadge);
boolean canShowBadge(String packageName, int uid);
boolean badgingEnabled(UserHandle userHandle);
diff --git a/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.java
new file mode 100644
index 0000000..fde45f71
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsJobService.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.notification;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+
+/**
+ * JobService implementation for scheduling the notification informing users about
+ * notification permissions updates and taking them to review their existing permissions.
+ * @hide
+ */
+public class ReviewNotificationPermissionsJobService extends JobService {
+ public static final String TAG = "ReviewNotificationPermissionsJobService";
+
+ @VisibleForTesting
+ protected static final int JOB_ID = 225373531;
+
+ /**
+ * Schedule a new job that will show a notification the specified amount of time in the future.
+ */
+ public static void scheduleJob(Context context, long rescheduleTimeMillis) {
+ JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+ // if the job already exists for some reason, cancel & reschedule
+ if (jobScheduler.getPendingJob(JOB_ID) != null) {
+ jobScheduler.cancel(JOB_ID);
+ }
+ ComponentName component = new ComponentName(
+ context, ReviewNotificationPermissionsJobService.class);
+ JobInfo newJob = new JobInfo.Builder(JOB_ID, component)
+ .setPersisted(true) // make sure it'll still get rescheduled after reboot
+ .setMinimumLatency(rescheduleTimeMillis) // run after specified amount of time
+ .build();
+ jobScheduler.schedule(newJob);
+ }
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ // While jobs typically should be run on different threads, this
+ // job only posts a notification, which is not a long-running operation
+ // as notification posting is asynchronous.
+ NotificationManagerInternal nmi =
+ LocalServices.getService(NotificationManagerInternal.class);
+ nmi.sendReviewPermissionsNotification();
+
+ // once the notification is posted, the job is done, so no need to
+ // keep it alive afterwards
+ return false;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ // If we're interrupted for some reason, try again (though this may not
+ // ever happen due to onStartJob not leaving a job running after being
+ // called)
+ return true;
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ReviewNotificationPermissionsReceiver.java b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsReceiver.java
new file mode 100644
index 0000000..b99aeac
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ReviewNotificationPermissionsReceiver.java
@@ -0,0 +1,122 @@
+/*
+ * 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.notification;
+
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * Broadcast receiver for intents that come from the "review notification permissions" notification,
+ * shown to users who upgrade to T from an earlier OS to inform them of notification setup changes
+ * and invite them to review their notification permissions.
+ */
+public class ReviewNotificationPermissionsReceiver extends BroadcastReceiver {
+ public static final String TAG = "ReviewNotifPermissions";
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ // 7 days in millis, as the amount of time to wait before re-sending the notification
+ private static final long JOB_RESCHEDULE_TIME = 1000 /* millis */ * 60 /* seconds */
+ * 60 /* minutes */ * 24 /* hours */ * 7 /* days */;
+
+ static IntentFilter getFilter() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(NotificationManagerService.REVIEW_NOTIF_ACTION_REMIND);
+ filter.addAction(NotificationManagerService.REVIEW_NOTIF_ACTION_DISMISS);
+ filter.addAction(NotificationManagerService.REVIEW_NOTIF_ACTION_CANCELED);
+ return filter;
+ }
+
+ // Cancels the "review notification permissions" notification.
+ @VisibleForTesting
+ protected void cancelNotification(Context context) {
+ NotificationManager nm = context.getSystemService(NotificationManager.class);
+ if (nm != null) {
+ nm.cancel(NotificationManagerService.TAG,
+ SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS);
+ } else {
+ Slog.w(TAG, "could not cancel notification: NotificationManager not found");
+ }
+ }
+
+ @VisibleForTesting
+ protected void rescheduleNotification(Context context) {
+ ReviewNotificationPermissionsJobService.scheduleJob(context, JOB_RESCHEDULE_TIME);
+ // log if needed
+ if (DEBUG) {
+ Slog.d(TAG, "Scheduled review permissions notification for on or after: "
+ + LocalDateTime.now(ZoneId.systemDefault())
+ .plus(JOB_RESCHEDULE_TIME, ChronoUnit.MILLIS));
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(NotificationManagerService.REVIEW_NOTIF_ACTION_REMIND)) {
+ // Reschedule the notification for 7 days in the future
+ rescheduleNotification(context);
+
+ // note that the user has interacted; no longer needed to show the initial
+ // notification
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED);
+ cancelNotification(context);
+ } else if (action.equals(NotificationManagerService.REVIEW_NOTIF_ACTION_DISMISS)) {
+ // user dismissed; write to settings so we don't show ever again
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_DISMISSED);
+ cancelNotification(context);
+ } else if (action.equals(NotificationManagerService.REVIEW_NOTIF_ACTION_CANCELED)) {
+ // we may get here from the user swiping away the notification,
+ // or from the notification being canceled in any other way.
+ // only in the case that the user hasn't interacted with it in
+ // any other way yet, reschedule
+ int notifState = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ /* default */ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN);
+ if (notifState == NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW) {
+ // user hasn't interacted in the past, so reschedule once and then note that the
+ // user *has* interacted now so we don't re-reschedule if they swipe again
+ rescheduleNotification(context);
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED);
+ } else if (notifState == NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN) {
+ // swiping away on a rescheduled notification; mark as interacted and
+ // don't reschedule again.
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index 2824585..3911994 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -34,13 +34,14 @@
import android.content.pm.ApkChecksum;
import android.content.pm.Checksum;
import android.content.pm.IOnChecksumsReadyListener;
-import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
import android.content.pm.SigningDetails.SignatureSchemeVersion;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
+import android.os.Environment;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -63,7 +64,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.security.VerityUtils;
-import com.android.server.LocalServices;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import java.io.ByteArrayOutputStream;
@@ -637,9 +637,18 @@
return null;
}
+ private static boolean containsFile(File dir, String filePath) {
+ if (dir == null) {
+ return false;
+ }
+ return FileUtils.contains(dir.getAbsolutePath(), filePath);
+ }
+
private static ApkChecksum extractHashFromFS(String split, String filePath) {
// verity first
- {
+ // Skip /product folder.
+ // TODO(b/231354111): remove this hack once we are allowed to change SELinux rules.
+ if (!containsFile(Environment.getProductDirectory(), filePath)) {
byte[] hash = VerityUtils.getFsverityRootHash(filePath);
if (hash != null) {
return new ApkChecksum(split, TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, hash);
diff --git a/services/core/java/com/android/server/pm/AppIdSettingMap.java b/services/core/java/com/android/server/pm/AppIdSettingMap.java
index b41a0b8..20c67f8 100644
--- a/services/core/java/com/android/server/pm/AppIdSettingMap.java
+++ b/services/core/java/com/android/server/pm/AppIdSettingMap.java
@@ -19,6 +19,7 @@
import android.os.Process;
import android.util.Log;
+import com.android.server.utils.SnapshotCache;
import com.android.server.utils.WatchedArrayList;
import com.android.server.utils.WatchedSparseArray;
import com.android.server.utils.Watcher;
@@ -34,10 +35,28 @@
* index to the corresponding SettingBase object is (appId - FIRST_APPLICATION_ID). If an app ID
* doesn't exist (i.e., app is not installed), we fill the corresponding entry with null.
*/
- private WatchedArrayList<SettingBase> mNonSystemSettings = new WatchedArrayList<>();
- private WatchedSparseArray<SettingBase> mSystemSettings = new WatchedSparseArray<>();
+ private final WatchedArrayList<SettingBase> mNonSystemSettings;
+ private final SnapshotCache<WatchedArrayList<SettingBase>> mNonSystemSettingsSnapshot;
+ private final WatchedSparseArray<SettingBase> mSystemSettings;
+ private final SnapshotCache<WatchedSparseArray<SettingBase>> mSystemSettingsSnapshot;
private int mFirstAvailableAppId = Process.FIRST_APPLICATION_UID;
+ AppIdSettingMap() {
+ mNonSystemSettings = new WatchedArrayList<>();
+ mNonSystemSettingsSnapshot = new SnapshotCache.Auto<>(
+ mNonSystemSettings, mNonSystemSettings, "AppIdSettingMap.mNonSystemSettings");
+ mSystemSettings = new WatchedSparseArray<>();
+ mSystemSettingsSnapshot = new SnapshotCache.Auto<>(
+ mSystemSettings, mSystemSettings, "AppIdSettingMap.mSystemSettings");
+ }
+
+ AppIdSettingMap(AppIdSettingMap orig) {
+ mNonSystemSettings = orig.mNonSystemSettingsSnapshot.snapshot();
+ mNonSystemSettingsSnapshot = new SnapshotCache.Sealed<>();
+ mSystemSettings = orig.mSystemSettingsSnapshot.snapshot();
+ mSystemSettingsSnapshot = new SnapshotCache.Sealed<>();
+ }
+
/** Returns true if the requested AppID was valid and not already registered. */
public boolean registerExistingAppId(int appId, SettingBase setting, Object name) {
if (appId >= Process.FIRST_APPLICATION_UID) {
@@ -134,10 +153,7 @@
}
public AppIdSettingMap snapshot() {
- AppIdSettingMap l = new AppIdSettingMap();
- mNonSystemSettings.snapshot(l.mNonSystemSettings, mNonSystemSettings);
- mSystemSettings.snapshot(l.mSystemSettings, mSystemSettings);
- return l;
+ return new AppIdSettingMap(this);
}
public void registerObserver(Watcher observer) {
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
new file mode 100644
index 0000000..7004c73
--- /dev/null
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -0,0 +1,773 @@
+/*
+ * 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 static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.server.pm.AppsFilterUtils.canQueryViaComponents;
+import static com.android.server.pm.AppsFilterUtils.requestsQueryAllPackages;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.SigningDetails;
+import android.os.Binder;
+import android.os.Process;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.function.QuadFunction;
+import com.android.server.om.OverlayReferenceMapper;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
+import com.android.server.utils.SnapshotCache;
+import com.android.server.utils.Watched;
+import com.android.server.utils.WatchedArrayList;
+import com.android.server.utils.WatchedArrayMap;
+import com.android.server.utils.WatchedArraySet;
+import com.android.server.utils.WatchedSparseBooleanMatrix;
+import com.android.server.utils.WatchedSparseSetArray;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * AppsFilter is the entity responsible for filtering visibility between apps based on declarations
+ * in their manifests. This class implements the unlocked, read-only methods of AppsFilter.
+ * See {@link AppsFilterImpl} for the write methods that updates the internal structures.
+ */
+public abstract class AppsFilterBase implements AppsFilterSnapshot {
+ protected static final String TAG = "AppsFilter";
+
+ // Logs all filtering instead of enforcing
+ protected static final boolean DEBUG_ALLOW_ALL = false;
+ protected static final boolean DEBUG_LOGGING = false;
+ public static final boolean DEBUG_TRACING = false;
+
+ /**
+ * This contains a list of app UIDs that are implicitly queryable because another app explicitly
+ * interacted with it. For example, if application A starts a service in application B,
+ * application B is implicitly allowed to query for application A; regardless of any manifest
+ * entries.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mImplicitlyQueryable;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot;
+
+ /**
+ * This contains a list of app UIDs that are implicitly queryable because another app explicitly
+ * interacted with it, but could keep across package updates. For example, if application A
+ * grants persistable uri permission to application B; regardless of any manifest entries.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mRetainedImplicitlyQueryableSnapshot;
+
+ /**
+ * A mapping from the set of App IDs that query other App IDs via package name to the
+ * list of packages that they can see.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mQueriesViaPackage;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot;
+
+ /**
+ * A mapping from the set of App IDs that query others via component match to the list
+ * of packages that the they resolve to.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mQueriesViaComponent;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot;
+
+ /**
+ * A mapping from the set of App IDs that query other App IDs via library name to the
+ * list of packages that they can see.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary;
+ @NonNull
+ protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
+
+ /**
+ * Executor for running reasonably short background tasks such as building the initial
+ * visibility cache.
+ */
+ protected Executor mBackgroundExecutor;
+
+ /**
+ * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of
+ * protected broadcast. This in turn invalidates all prior additions and require a very
+ * computationally expensive recomputing.
+ * Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps.
+ */
+ protected boolean mQueriesViaComponentRequireRecompute = false;
+
+ /**
+ * A set of App IDs that are always queryable by any package, regardless of their manifest
+ * content.
+ */
+ @NonNull
+ @Watched
+ protected WatchedArraySet<Integer> mForceQueryable;
+ @NonNull
+ protected SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot;
+
+ /**
+ * The set of package names provided by the device that should be force queryable regardless of
+ * their manifest contents.
+ */
+ @NonNull
+ protected String[] mForceQueryableByDevicePackageNames;
+ @NonNull
+ /** True if all system apps should be made queryable by default. */
+ protected boolean mSystemAppsQueryable;
+ @NonNull
+ protected FeatureConfig mFeatureConfig;
+ @NonNull
+ protected OverlayReferenceMapper mOverlayReferenceMapper;
+ @Nullable
+ protected SigningDetails mSystemSigningDetails;
+
+ @NonNull
+ @Watched
+ protected WatchedArrayList<String> mProtectedBroadcasts;
+ @NonNull
+ protected SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot;
+
+ /**
+ * This structure maps uid -> uid and indicates whether access from the first should be
+ * filtered to the second. It's essentially a cache of the
+ * {@link #shouldFilterApplicationInternal(PackageDataSnapshot, int, Object,
+ * PackageStateInternal, int)} call.
+ * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
+ * initial scam and is empty until {@link #mSystemReady} is true.
+ */
+ @NonNull
+ @Watched
+ protected WatchedSparseBooleanMatrix mShouldFilterCache;
+ @NonNull
+ protected SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot;
+
+ protected volatile boolean mSystemReady = false;
+
+ protected boolean isForceQueryable(int callingAppId) {
+ return mForceQueryable.contains(callingAppId);
+ }
+
+ protected boolean isQueryableViaPackage(int callingAppId, int targetAppId) {
+ return mQueriesViaPackage.contains(callingAppId, targetAppId);
+ }
+
+ protected boolean isQueryableViaComponent(int callingAppId, int targetAppId) {
+ return mQueriesViaComponent.contains(callingAppId, targetAppId);
+ }
+
+ protected boolean isImplicitlyQueryable(int callingAppId, int targetAppId) {
+ return mImplicitlyQueryable.contains(callingAppId, targetAppId);
+ }
+
+ protected boolean isRetainedImplicitlyQueryable(int callingAppId, int targetAppId) {
+ return mRetainedImplicitlyQueryable.contains(callingAppId, targetAppId);
+ }
+
+ protected boolean isQueryableViaUsesLibrary(int callingAppId, int targetAppId) {
+ return mQueryableViaUsesLibrary.contains(callingAppId, targetAppId);
+ }
+
+ protected boolean isQueryableViaComponentWhenRequireRecompute(
+ ArrayMap<String, ? extends PackageStateInternal> existingSettings,
+ PackageStateInternal callingPkgSetting,
+ ArraySet<PackageStateInternal> callingSharedPkgSettings,
+ AndroidPackage targetPkg,
+ int callingAppId, int targetAppId) {
+ // Do no recompute or use mQueriesViaComponent if it's stale in snapshot
+ // Since we know we are in the snapshot, no need to acquire mLock because
+ // mProtectedBroadcasts will not change
+ if (callingPkgSetting != null) {
+ if (callingPkgSetting.getPkg() != null
+ && canQueryViaComponents(callingPkgSetting.getPkg(), targetPkg,
+ mProtectedBroadcasts)) {
+ return true;
+ }
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ final AndroidPackage pkg =
+ callingSharedPkgSettings.valueAt(i).getPkg();
+ if (pkg != null && canQueryViaComponents(pkg, targetPkg,
+ mProtectedBroadcasts)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageDataSnapshot,
+ * PackageStateInternal, int[], ArrayMap)}
+ */
+ @Override
+ @Nullable
+ public SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
+ PackageStateInternal setting, int[] users,
+ ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
+ if (isForceQueryable(setting.getAppId())) {
+ return null;
+ }
+ // let's reserve max memory to limit the number of allocations
+ SparseArray<int[]> result = new SparseArray<>(users.length);
+ for (int u = 0; u < users.length; u++) {
+ final int userId = users[u];
+ int[] appIds = new int[existingSettings.size()];
+ int[] buffer = null;
+ int allowListSize = 0;
+ for (int i = existingSettings.size() - 1; i >= 0; i--) {
+ final PackageStateInternal existingSetting = existingSettings.valueAt(i);
+ final int existingAppId = existingSetting.getAppId();
+ if (existingAppId < Process.FIRST_APPLICATION_UID) {
+ continue;
+ }
+ final int loc = Arrays.binarySearch(appIds, 0, allowListSize, existingAppId);
+ if (loc >= 0) {
+ continue;
+ }
+ final int existingUid = UserHandle.getUid(userId, existingAppId);
+ if (!shouldFilterApplication(snapshot, existingUid, existingSetting, setting,
+ userId)) {
+ if (buffer == null) {
+ buffer = new int[appIds.length];
+ }
+ final int insert = ~loc;
+ System.arraycopy(appIds, insert, buffer, 0, allowListSize - insert);
+ appIds[insert] = existingAppId;
+ System.arraycopy(buffer, 0, appIds, insert + 1, allowListSize - insert);
+ allowListSize++;
+ }
+ }
+ result.put(userId, Arrays.copyOf(appIds, allowListSize));
+ }
+ return result;
+ }
+
+ /**
+ * This api does type conversion on the <existingSettings> parameter.
+ */
+ @VisibleForTesting(visibility = PRIVATE)
+ @Nullable
+ SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
+ PackageStateInternal setting, int[] users,
+ WatchedArrayMap<String, ? extends PackageStateInternal> existingSettings) {
+ return getVisibilityAllowList(snapshot, setting, users,
+ existingSettings.untrackedStorage());
+ }
+
+ /**
+ * See
+ * {@link AppsFilterSnapshot#shouldFilterApplication(PackageDataSnapshot, int, Object,
+ * PackageStateInternal, int)}
+ */
+ @Override
+ public boolean shouldFilterApplication(PackageDataSnapshot snapshot, int callingUid,
+ @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId) {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
+ }
+ try {
+ int callingAppId = UserHandle.getAppId(callingUid);
+ if (callingAppId < Process.FIRST_APPLICATION_UID
+ || targetPkgSetting.getAppId() < Process.FIRST_APPLICATION_UID
+ || callingAppId == targetPkgSetting.getAppId()) {
+ return false;
+ }
+ if (mSystemReady) { // use cache
+ if (!shouldFilterApplicationUsingCache(callingUid,
+ targetPkgSetting.getAppId(),
+ userId)) {
+ return false;
+ }
+ } else {
+ if (!shouldFilterApplicationInternal(snapshot,
+ callingUid, callingSetting, targetPkgSetting, userId)) {
+ return false;
+ }
+ }
+ if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) {
+ log(callingSetting, targetPkgSetting, "BLOCKED");
+ }
+ return !DEBUG_ALLOW_ALL;
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ }
+
+ protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
+ final int callingIndex = mShouldFilterCache.indexOfKey(callingUid);
+ if (callingIndex < 0) {
+ Slog.wtf(TAG, "Encountered calling uid with no cached rules: "
+ + callingUid);
+ return true;
+ }
+ final int targetUid = UserHandle.getUid(userId, appId);
+ final int targetIndex = mShouldFilterCache.indexOfKey(targetUid);
+ if (targetIndex < 0) {
+ Slog.w(TAG, "Encountered calling -> target with no cached rules: "
+ + callingUid + " -> " + targetUid);
+ return true;
+ }
+ return mShouldFilterCache.valueAt(callingIndex, targetIndex);
+ }
+
+ protected boolean shouldFilterApplicationInternal(PackageDataSnapshot snapshot, int callingUid,
+ Object callingSetting, PackageStateInternal targetPkgSetting, int targetUserId) {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
+ }
+ try {
+ final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
+ if (!featureEnabled) {
+ if (DEBUG_LOGGING) {
+ Slog.d(TAG, "filtering disabled; skipped");
+ }
+ return false;
+ }
+ if (callingSetting == null) {
+ Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
+ return true;
+ }
+ final PackageStateInternal callingPkgSetting;
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
+ }
+ final ArraySet<PackageStateInternal> callingSharedPkgSettings = new ArraySet<>();
+
+ if (callingSetting instanceof PackageStateInternal) {
+ final PackageStateInternal packageState = (PackageStateInternal) callingSetting;
+ if (packageState.hasSharedUser()) {
+ callingPkgSetting = null;
+ callingSharedPkgSettings.addAll(getSharedUserPackages(
+ packageState.getSharedUserAppId(), snapshot.getAllSharedUsers()));
+
+ } else {
+ callingPkgSetting = packageState;
+ }
+ } else {
+ callingPkgSetting = null;
+ callingSharedPkgSettings.addAll(
+ ((SharedUserSetting) callingSetting).getPackageStates());
+ }
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ if (callingPkgSetting != null) {
+ if (callingPkgSetting.getPkg() != null
+ && !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "DISABLED");
+ }
+ return false;
+ }
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ final AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg();
+ if (pkg != null && !mFeatureConfig.packageIsEnabled(pkg)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "DISABLED");
+ }
+ return false;
+ }
+ }
+ }
+
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "getAppId");
+ }
+ final int callingAppId;
+ if (callingPkgSetting != null) {
+ callingAppId = callingPkgSetting.getAppId();
+ } else {
+ // all should be the same
+ callingAppId = callingSharedPkgSettings.valueAt(0).getAppId();
+ }
+ final int targetAppId = targetPkgSetting.getAppId();
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ if (callingAppId == targetAppId) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "same app id");
+ }
+ return false;
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "requestsQueryAllPackages");
+ }
+ if (callingPkgSetting != null) {
+ if (callingPkgSetting.getPkg() != null
+ && requestsQueryAllPackages(callingPkgSetting.getPkg())) {
+ return false;
+ }
+ } else {
+ for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
+ AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg();
+ if (pkg != null && requestsQueryAllPackages(pkg)) {
+ return false;
+ }
+ }
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ // This package isn't technically installed and won't be written to settings, so we can
+ // treat it as filtered until it's available again.
+ final AndroidPackage targetPkg = targetPkgSetting.getPkg();
+ if (targetPkg == null) {
+ if (DEBUG_LOGGING) {
+ Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null");
+ }
+ return true;
+ }
+ if (targetPkg.isStaticSharedLibrary()) {
+ // not an app, this filtering takes place at a higher level
+ return false;
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
+ }
+ if (isForceQueryable(targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "force queryable");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
+ }
+ if (isQueryableViaPackage(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queries package");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
+ }
+ if (!mQueriesViaComponentRequireRecompute) {
+ if (isQueryableViaComponent(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queries component");
+ }
+ return false;
+ }
+ } else { // mQueriesViaComponent is stale
+ if (isQueryableViaComponentWhenRequireRecompute(snapshot.getPackageStates(),
+ callingPkgSetting, callingSharedPkgSettings, targetPkg,
+ callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queries component");
+ }
+ return false;
+ }
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
+ }
+ final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
+ if (isImplicitlyQueryable(callingUid, targetUid)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "implicitly queryable for user");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
+ }
+ final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
+ if (isRetainedImplicitlyQueryable(callingUid, targetUid)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting,
+ "retained implicitly queryable for user");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper");
+ }
+ final String targetName = targetPkg.getPackageName();
+ if (!callingSharedPkgSettings.isEmpty()) {
+ int size = callingSharedPkgSettings.size();
+ for (int index = 0; index < size; index++) {
+ PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(index);
+ if (mOverlayReferenceMapper.isValidActor(targetName,
+ pkgSetting.getPackageName())) {
+ if (DEBUG_LOGGING) {
+ log(callingPkgSetting, targetPkgSetting,
+ "matches shared user of package that acts on target of "
+ + "overlay");
+ }
+ return false;
+ }
+ }
+ } else {
+ if (mOverlayReferenceMapper.isValidActor(targetName,
+ callingPkgSetting.getPackageName())) {
+ if (DEBUG_LOGGING) {
+ log(callingPkgSetting, targetPkgSetting, "acts on target of overlay");
+ }
+ return false;
+ }
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ try {
+ if (DEBUG_TRACING) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
+ }
+ if (isQueryableViaUsesLibrary(callingAppId, targetAppId)) {
+ if (DEBUG_LOGGING) {
+ log(callingSetting, targetPkgSetting, "queryable for library users");
+ }
+ return false;
+ }
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ return true;
+ } finally {
+ if (DEBUG_TRACING) {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+ }
+
+ /**
+ * See {@link AppsFilterSnapshot#canQueryPackage(AndroidPackage, String)}
+ */
+ @Override
+ public boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) {
+ int appId = UserHandle.getAppId(querying.getUid());
+ if (appId < Process.FIRST_APPLICATION_UID) {
+ return true;
+ }
+
+ // Check if FILTER_APPLICATION_QUERY is enabled on the given package.
+ if (!mFeatureConfig.packageIsEnabled(querying)) {
+ return true;
+ }
+
+ if (requestsQueryAllPackages(querying)) {
+ return true;
+ }
+
+ return !querying.getQueriesPackages().isEmpty()
+ && querying.getQueriesPackages().contains(potentialTarget);
+ }
+
+ private static void log(Object callingSetting, PackageStateInternal targetPkgSetting,
+ String description) {
+ Slog.i(TAG,
+ "interaction: " + (callingSetting == null ? "system" : callingSetting) + " -> "
+ + targetPkgSetting + " " + description);
+ }
+
+ protected ArraySet<? extends PackageStateInternal> getSharedUserPackages(int sharedUserAppId,
+ Collection<SharedUserSetting> sharedUserSettings) {
+ for (SharedUserSetting setting : sharedUserSettings) {
+ if (setting.mAppId != sharedUserAppId) {
+ continue;
+ }
+ return setting.getPackageStates();
+ }
+ return new ArraySet<>();
+ }
+
+ /**
+ * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[],
+ * QuadFunction)}
+ */
+ @Override
+ public void dumpQueries(
+ PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, int[] users,
+ QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid) {
+ final SparseArray<String> cache = new SparseArray<>();
+ ToString<Integer> expandPackages = input -> {
+ String cachedValue = cache.get(input);
+ if (cachedValue == null) {
+ final int callingUid = Binder.getCallingUid();
+ final int appId = UserHandle.getAppId(input);
+ String[] packagesForUid = null;
+ for (int i = 0, size = users.length; packagesForUid == null && i < size; i++) {
+ packagesForUid = getPackagesForUid.apply(callingUid, users[i], appId,
+ false /*isCallerInstantApp*/);
+ }
+ if (packagesForUid == null) {
+ cachedValue = "[app id " + input + " not installed]";
+ } else {
+ cachedValue = packagesForUid.length == 1 ? packagesForUid[0]
+ : "[" + TextUtils.join(",", packagesForUid) + "]";
+ }
+ cache.put(input, cachedValue);
+ }
+ return cachedValue;
+ };
+ pw.println();
+ pw.println("Queries:");
+ dumpState.onTitlePrinted();
+ if (!mFeatureConfig.isGloballyEnabled()) {
+ pw.println(" DISABLED");
+ if (!DEBUG_LOGGING) {
+ return;
+ }
+ }
+ pw.println(" system apps queryable: " + mSystemAppsQueryable);
+ dumpQueryables(pw, filteringAppId, users, expandPackages);
+ }
+
+ protected void dumpQueryables(PrintWriter pw, @Nullable Integer filteringAppId, int[] users,
+ ToString<Integer> expandPackages) {
+ dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
+ "forceQueryable", " ", expandPackages);
+ pw.println(" queries via package name:");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
+ pw.println(" queries via component:");
+ dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
+ pw.println(" queryable via interaction:");
+ for (int user : users) {
+ pw.append(" User ").append(Integer.toString(user)).println(":");
+ dumpQueriesMap(pw,
+ filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+ mImplicitlyQueryable, " ", expandPackages);
+ dumpQueriesMap(pw,
+ filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
+ mRetainedImplicitlyQueryable, " ", expandPackages);
+ }
+ pw.println(" queryable via uses-library:");
+ dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ",
+ expandPackages);
+ }
+
+ private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
+ WatchedSparseSetArray<Integer> queriesMap, String spacing,
+ @Nullable ToString<Integer> toString) {
+ for (int i = 0; i < queriesMap.size(); i++) {
+ Integer callingId = queriesMap.keyAt(i);
+ if (Objects.equals(callingId, filteringId)) {
+ // don't filter target package names if the calling is filteringId
+ dumpPackageSet(
+ pw, null /*filteringId*/, queriesMap.get(callingId),
+ toString == null
+ ? callingId.toString()
+ : toString.toString(callingId),
+ spacing, toString);
+ } else {
+ dumpPackageSet(
+ pw, filteringId, queriesMap.get(callingId),
+ toString == null
+ ? callingId.toString()
+ : toString.toString(callingId),
+ spacing, toString);
+ }
+ }
+ }
+
+ protected interface ToString<T> {
+ String toString(T input);
+ }
+
+ private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId,
+ ArraySet<T> targetPkgSet, String subTitle, String spacing,
+ @Nullable ToString<T> toString) {
+ if (targetPkgSet != null && targetPkgSet.size() > 0
+ && (filteringId == null || targetPkgSet.contains(filteringId))) {
+ pw.append(spacing).append(subTitle).println(":");
+ for (T item : targetPkgSet) {
+ if (filteringId == null || Objects.equals(filteringId, item)) {
+ pw.append(spacing).append(" ")
+ .println(toString == null ? item : toString.toString(item));
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index f757405..952711d 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -22,210 +22,68 @@
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.server.pm.AppsFilterUtils.canQueryAsInstaller;
+import static com.android.server.pm.AppsFilterUtils.canQueryViaComponents;
+import static com.android.server.pm.AppsFilterUtils.canQueryViaPackage;
+import static com.android.server.pm.AppsFilterUtils.canQueryViaUsesLibrary;
+import static com.android.server.pm.AppsFilterUtils.requestsQueryAllPackages;
-import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.SigningDetails;
import android.content.pm.UserInfo;
-import android.os.Binder;
-import android.os.Process;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.DeviceConfig;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
-import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.function.QuadFunction;
import com.android.server.FgThread;
import com.android.server.compat.CompatChange;
import com.android.server.om.OverlayReferenceMapper;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.pkg.component.ParsedComponent;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
-import com.android.server.pm.pkg.component.ParsedIntentInfo;
-import com.android.server.pm.pkg.component.ParsedMainComponent;
-import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
-import com.android.server.utils.Watched;
import com.android.server.utils.WatchedArrayList;
-import com.android.server.utils.WatchedArrayMap;
import com.android.server.utils.WatchedArraySet;
import com.android.server.utils.WatchedSparseBooleanMatrix;
import com.android.server.utils.WatchedSparseSetArray;
import com.android.server.utils.Watcher;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
-import java.util.StringTokenizer;
import java.util.concurrent.Executor;
/**
- * The entity responsible for filtering visibility between apps based on declarations in their
- * manifests.
+ * Implementation of the methods that update the internal structures of AppsFilter. Because of the
+ * mutations, all the read accesses to those internal structures need to be locked, thus extending
+ * {@link AppsFilterLocked}.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable {
-
- private static final String TAG = "AppsFilter";
-
- // Logs all filtering instead of enforcing
- private static final boolean DEBUG_ALLOW_ALL = false;
- private static final boolean DEBUG_LOGGING = false;
- private static final boolean DEBUG_TRACING = false;
-
- /**
- * This contains a list of app UIDs that are implicitly queryable because another app explicitly
- * interacted with it. For example, if application A starts a service in application B,
- * application B is implicitly allowed to query for application A; regardless of any manifest
- * entries.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mImplicitlyQueryable;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot;
-
- /**
- * This contains a list of app UIDs that are implicitly queryable because another app explicitly
- * interacted with it, but could keep across package updates. For example, if application A
- * grants persistable uri permission to application B; regardless of any manifest entries.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable;
- private final SnapshotCache<WatchedSparseSetArray<Integer>>
- mRetainedImplicitlyQueryableSnapshot;
-
- /**
- * A mapping from the set of App IDs that query other App IDs via package name to the
- * list of packages that they can see.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueriesViaPackage;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot;
-
- /**
- * A mapping from the set of App IDs that query others via component match to the list
- * of packages that the they resolve to.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueriesViaComponent;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot;
-
- /**
- * A mapping from the set of App IDs that query other App IDs via library name to the
- * list of packages that they can see.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary;
- private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;
-
- /**
- * Executor for running reasonably short background tasks such as building the initial
- * visibility cache.
- */
- private final Executor mBackgroundExecutor;
-
- /**
- * Pending full recompute of mQueriesViaComponent. Occurs when a package adds a new set of
- * protected broadcast. This in turn invalidates all prior additions and require a very
- * computationally expensive recomputing.
- * Full recompute is done lazily at the point when we use mQueriesViaComponent to filter apps.
- */
- private boolean mQueriesViaComponentRequireRecompute = false;
-
- /**
- * A set of App IDs that are always queryable by any package, regardless of their manifest
- * content.
- */
- @GuardedBy("mLock")
- @Watched
- private final WatchedArraySet<Integer> mForceQueryable;
- private final SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot;
-
- /**
- * The set of package names provided by the device that should be force queryable regardless of
- * their manifest contents.
- */
- private final String[] mForceQueryableByDevicePackageNames;
-
- /** True if all system apps should be made queryable by default. */
- private final boolean mSystemAppsQueryable;
- private final FeatureConfig mFeatureConfig;
- private final OverlayReferenceMapper mOverlayReferenceMapper;
- private SigningDetails mSystemSigningDetails;
-
- @GuardedBy("mLock")
- @Watched
- private final WatchedArrayList<String> mProtectedBroadcasts;
- private final SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot;
-
- private final Object mCacheLock = new Object();
-
- private final boolean mIsSnapshot;
-
- /**
- * This structure maps uid -> uid and indicates whether access from the first should be
- * filtered to the second. It's essentially a cache of the
- * {@link #shouldFilterApplicationInternal(PackageDataSnapshot, int, Object,
- * PackageStateInternal, int)} call.
- * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
- * initial scam and is empty until {@link #mSystemReady} is true.
- */
- @GuardedBy("mCacheLock")
- @NonNull
- private final WatchedSparseBooleanMatrix mShouldFilterCache;
- private final SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot;
-
- private volatile boolean mSystemReady = false;
-
- /**
- * Guards the accesses for the list/set fields except for {@link #mShouldFilterCache}
- */
- private final Object mLock = new Object();
-
+public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, Snappable {
/**
* A cached snapshot.
*/
- private final SnapshotCache<AppsFilterImpl> mSnapshot;
-
- private SnapshotCache<AppsFilterImpl> makeCache() {
- return new SnapshotCache<AppsFilterImpl>(this, this) {
- @Override
- public AppsFilterImpl createSnapshot() {
- AppsFilterImpl s = new AppsFilterImpl(mSource);
- s.mWatchable.seal();
- return s;
- }
- };
- }
+ @NonNull
+ private SnapshotCache<AppsFilterSnapshot> mSnapshot;
/**
* Watchable machinery
@@ -323,47 +181,12 @@
mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
- mSnapshot = makeCache();
- mIsSnapshot = false;
- }
-
- /**
- * The copy constructor is used by PackageManagerService to construct a snapshot.
- */
- private AppsFilterImpl(AppsFilterImpl orig) {
- synchronized (orig.mLock) {
- mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
- mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
- mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot();
- mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>();
- mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot();
- mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>();
- mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot();
- mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>();
- mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
- mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
- mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
- mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
- mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
- mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
- }
- mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
- mForceQueryableByDevicePackageNames =
- Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
- orig.mForceQueryableByDevicePackageNames.length);
- mSystemAppsQueryable = orig.mSystemAppsQueryable;
- mFeatureConfig = orig.mFeatureConfig;
- mOverlayReferenceMapper = orig.mOverlayReferenceMapper;
- mSystemSigningDetails = orig.mSystemSigningDetails;
- synchronized (orig.mCacheLock) {
- mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot();
- mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>();
- }
-
- mBackgroundExecutor = null;
- mSnapshot = new SnapshotCache.Sealed<>();
- mSystemReady = orig.mSystemReady;
- mIsSnapshot = true;
+ mSnapshot = new SnapshotCache<AppsFilterSnapshot>(this, this) {
+ @Override
+ public AppsFilterSnapshot createSnapshot() {
+ return new AppsFilterSnapshotImpl(AppsFilterImpl.this);
+ }
+ };
}
/**
@@ -375,38 +198,8 @@
return mSnapshot.snapshot();
}
- @VisibleForTesting(visibility = PRIVATE)
- public interface FeatureConfig {
-
- /** Called when the system is ready and components can be queried. */
- void onSystemReady();
-
- /** @return true if we should filter apps at all. */
- boolean isGloballyEnabled();
-
- /** @return true if the feature is enabled for the given package. */
- boolean packageIsEnabled(AndroidPackage pkg);
-
- /** @return true if debug logging is enabled for the given package. */
- boolean isLoggingEnabled(int appId);
-
- /**
- * Turns on logging for the given appId
- *
- * @param enable true if logging should be enabled, false if disabled.
- */
- void enableLogging(int appId, boolean enable);
-
- /**
- * Initializes the package enablement state for the given package. This gives opportunity
- * to do any expensive operations ahead of the actual checks.
- *
- * @param removed true if adding, false if removing
- */
- void updatePackageState(PackageStateInternal setting, boolean removed);
- }
-
- private static class FeatureConfigImpl implements FeatureConfig, CompatChange.ChangeListener {
+ private static class FeatureConfigImpl implements FeatureConfig,
+ CompatChange.ChangeListener {
private static final String FILTERING_ENABLED_NAME = "package_query_filtering_enabled";
private final PackageManagerServiceInjector mInjector;
private final PackageManagerInternal mPmInternal;
@@ -424,6 +217,14 @@
mInjector = injector;
}
+ FeatureConfigImpl(FeatureConfigImpl orig) {
+ mInjector = null;
+ mPmInternal = null;
+ mFeatureEnabled = orig.mFeatureEnabled;
+ mDisabledPackages.addAll(orig.mDisabledPackages);
+ mLoggingEnabled = orig.mLoggingEnabled;
+ }
+
public void setAppsFilter(AppsFilterImpl filter) {
mAppsFilter = filter;
}
@@ -535,10 +336,18 @@
enableLogging(setting.getAppId(), enableLogging);
if (removed) {
mDisabledPackages.remove(setting.getPackageName());
+ if (mAppsFilter != null) {
+ mAppsFilter.onChanged();
+ }
} else if (setting.getPkg() != null) {
updateEnabledState(setting.getPkg());
}
}
+
+ @Override
+ public FeatureConfig snapshot() {
+ return new FeatureConfigImpl(this);
+ }
}
/** Builder method for an AppsFilter */
@@ -571,133 +380,6 @@
return mFeatureConfig;
}
- /** Returns true if the querying package may query for the potential target package */
- private static boolean canQueryViaComponents(AndroidPackage querying,
- AndroidPackage potentialTarget, WatchedArrayList<String> protectedBroadcasts) {
- if (!querying.getQueriesIntents().isEmpty()) {
- for (Intent intent : querying.getQueriesIntents()) {
- if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) {
- return true;
- }
- }
- }
- if (!querying.getQueriesProviders().isEmpty()
- && matchesProviders(querying.getQueriesProviders(), potentialTarget)) {
- return true;
- }
- return false;
- }
-
- private static boolean canQueryViaPackage(AndroidPackage querying,
- AndroidPackage potentialTarget) {
- return !querying.getQueriesPackages().isEmpty()
- && querying.getQueriesPackages().contains(potentialTarget.getPackageName());
- }
-
- private static boolean canQueryAsInstaller(PackageStateInternal querying,
- AndroidPackage potentialTarget) {
- final InstallSource installSource = querying.getInstallSource();
- if (potentialTarget.getPackageName().equals(installSource.installerPackageName)) {
- return true;
- }
- if (!installSource.isInitiatingPackageUninstalled
- && potentialTarget.getPackageName().equals(installSource.initiatingPackageName)) {
- return true;
- }
- return false;
- }
-
- private static boolean canQueryViaUsesLibrary(AndroidPackage querying,
- AndroidPackage potentialTarget) {
- if (potentialTarget.getLibraryNames().isEmpty()) {
- return false;
- }
- final List<String> libNames = potentialTarget.getLibraryNames();
- for (int i = 0, size = libNames.size(); i < size; i++) {
- final String libName = libNames.get(i);
- if (querying.getUsesLibraries().contains(libName)
- || querying.getUsesOptionalLibraries().contains(libName)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean matchesProviders(
- Set<String> queriesAuthorities, AndroidPackage potentialTarget) {
- for (int p = ArrayUtils.size(potentialTarget.getProviders()) - 1; p >= 0; p--) {
- ParsedProvider provider = potentialTarget.getProviders().get(p);
- if (!provider.isExported()) {
- continue;
- }
- if (provider.getAuthority() == null) {
- continue;
- }
- StringTokenizer authorities = new StringTokenizer(provider.getAuthority(), ";",
- false);
- while (authorities.hasMoreElements()) {
- if (queriesAuthorities.contains(authorities.nextToken())) {
- return true;
- }
- }
- }
- return false;
- }
-
- private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget,
- WatchedArrayList<String> protectedBroadcasts) {
- if (matchesAnyComponents(
- intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) {
- return true;
- }
- if (matchesAnyComponents(
- intent, potentialTarget.getActivities(), null /*protectedBroadcasts*/)) {
- return true;
- }
- if (matchesAnyComponents(intent, potentialTarget.getReceivers(), protectedBroadcasts)) {
- return true;
- }
- if (matchesAnyComponents(
- intent, potentialTarget.getProviders(), null /*protectedBroadcasts*/)) {
- return true;
- }
- return false;
- }
-
- private static boolean matchesAnyComponents(Intent intent,
- List<? extends ParsedMainComponent> components,
- WatchedArrayList<String> protectedBroadcasts) {
- for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) {
- ParsedMainComponent component = components.get(i);
- if (!component.isExported()) {
- continue;
- }
- if (matchesAnyFilter(intent, component, protectedBroadcasts)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
- WatchedArrayList<String> protectedBroadcasts) {
- List<ParsedIntentInfo> intents = component.getIntents();
- for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
- IntentFilter intentFilter = intents.get(i).getIntentFilter();
- if (matchesIntentFilter(intent, intentFilter, protectedBroadcasts)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
- @Nullable WatchedArrayList<String> protectedBroadcasts) {
- return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
- intent.getData(), intent.getCategories(), "AppsFilter", true,
- protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0;
- }
-
/**
* Grants access based on an interaction between a calling and target package, granting
* visibility of the caller from the target.
@@ -921,10 +603,6 @@
}
}
- private void updateEntireShouldFilterCache(PackageDataSnapshot snapshot) {
- updateEntireShouldFilterCache(snapshot, USER_ALL);
- }
-
private void updateEntireShouldFilterCache(PackageDataSnapshot snapshot, int subjectUserId) {
final ArrayMap<String, ? extends PackageStateInternal> settings =
snapshot.getPackageStates();
@@ -1110,6 +788,18 @@
}
}
+ @Override
+ protected boolean isQueryableViaComponentWhenRequireRecompute(
+ ArrayMap<String, ? extends PackageStateInternal> existingSettings,
+ PackageStateInternal callingPkgSetting,
+ ArraySet<PackageStateInternal> callingSharedPkgSettings,
+ AndroidPackage targetPkg,
+ int callingAppId, int targetAppId) {
+ // Recompute the whole mQueriesViaComponent because mProtectedBroadcasts have changed
+ recomputeComponentVisibility(existingSettings);
+ return isQueryableViaComponent(callingAppId, targetAppId);
+ }
+
/**
* This method recomputes all component / intent-based visibility and is intended to match the
* relevant logic of {@link #addPackageInternal(PackageStateInternal, ArrayMap)}
@@ -1144,67 +834,6 @@
}
/**
- * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageDataSnapshot,
- * PackageStateInternal, int[], ArrayMap)}
- */
- @Override
- @Nullable
- public SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
- PackageStateInternal setting, int[] users,
- ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
- synchronized (mLock) {
- if (mForceQueryable.contains(setting.getAppId())) {
- return null;
- }
- }
- // let's reserve max memory to limit the number of allocations
- SparseArray<int[]> result = new SparseArray<>(users.length);
- for (int u = 0; u < users.length; u++) {
- final int userId = users[u];
- int[] appIds = new int[existingSettings.size()];
- int[] buffer = null;
- int allowListSize = 0;
- for (int i = existingSettings.size() - 1; i >= 0; i--) {
- final PackageStateInternal existingSetting = existingSettings.valueAt(i);
- final int existingAppId = existingSetting.getAppId();
- if (existingAppId < Process.FIRST_APPLICATION_UID) {
- continue;
- }
- final int loc = Arrays.binarySearch(appIds, 0, allowListSize, existingAppId);
- if (loc >= 0) {
- continue;
- }
- final int existingUid = UserHandle.getUid(userId, existingAppId);
- if (!shouldFilterApplication(snapshot, existingUid, existingSetting, setting,
- userId)) {
- if (buffer == null) {
- buffer = new int[appIds.length];
- }
- final int insert = ~loc;
- System.arraycopy(appIds, insert, buffer, 0, allowListSize - insert);
- appIds[insert] = existingAppId;
- System.arraycopy(buffer, 0, appIds, insert + 1, allowListSize - insert);
- allowListSize++;
- }
- }
- result.put(userId, Arrays.copyOf(appIds, allowListSize));
- }
- return result;
- }
-
- /**
- * This api does type conversion on the <existingSettings> parameter.
- */
- @VisibleForTesting(visibility = PRIVATE)
- @Nullable
- SparseArray<int[]> getVisibilityAllowList(PackageDataSnapshot snapshot,
- PackageStateInternal setting, int[] users,
- WatchedArrayMap<String, ? extends PackageStateInternal> existingSettings) {
- return getVisibilityAllowList(snapshot, setting, users,
- existingSettings.untrackedStorage());
- }
-
- /**
* Equivalent to calling {@link #addPackage(PackageDataSnapshot, PackageStateInternal, boolean)}
* with {@code isReplace} equal to {@code false}.
*
@@ -1339,420 +968,6 @@
onChanged();
}
- private ArraySet<? extends PackageStateInternal> getSharedUserPackages(int sharedUserAppId,
- Collection<SharedUserSetting> sharedUserSettings) {
- for (SharedUserSetting setting : sharedUserSettings) {
- if (setting.mAppId != sharedUserAppId) {
- continue;
- }
- return setting.getPackageStates();
- }
- return new ArraySet<>();
- }
-
- /**
- * See
- * {@link AppsFilterSnapshot#shouldFilterApplication(PackageDataSnapshot, int, Object,
- * PackageStateInternal, int)}
- */
- @Override
- public boolean shouldFilterApplication(PackageDataSnapshot snapshot, int callingUid,
- @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId) {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
- }
- try {
- int callingAppId = UserHandle.getAppId(callingUid);
- if (callingAppId < Process.FIRST_APPLICATION_UID
- || targetPkgSetting.getAppId() < Process.FIRST_APPLICATION_UID
- || callingAppId == targetPkgSetting.getAppId()) {
- return false;
- }
- if (mSystemReady) { // use cache
- if (!shouldFilterApplicationUsingCache(callingUid,
- targetPkgSetting.getAppId(),
- userId)) {
- return false;
- }
- } else {
- if (!shouldFilterApplicationInternal(snapshot,
- callingUid, callingSetting, targetPkgSetting, userId)) {
- return false;
- }
- }
- if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(callingAppId)) {
- log(callingSetting, targetPkgSetting, "BLOCKED");
- }
- return !DEBUG_ALLOW_ALL;
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
- }
-
- private boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
- synchronized (mCacheLock) {
- final int callingIndex = mShouldFilterCache.indexOfKey(callingUid);
- if (callingIndex < 0) {
- Slog.wtf(TAG, "Encountered calling uid with no cached rules: "
- + callingUid);
- return true;
- }
- final int targetUid = UserHandle.getUid(userId, appId);
- final int targetIndex = mShouldFilterCache.indexOfKey(targetUid);
- if (targetIndex < 0) {
- Slog.w(TAG, "Encountered calling -> target with no cached rules: "
- + callingUid + " -> " + targetUid);
- return true;
- }
- return mShouldFilterCache.valueAt(callingIndex, targetIndex);
- }
- }
-
- @SuppressWarnings("GuardedBy")
- private boolean shouldFilterApplicationInternal(PackageDataSnapshot snapshot, int callingUid,
- Object callingSetting, PackageStateInternal targetPkgSetting, int targetUserId) {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
- }
- try {
- final boolean featureEnabled = mFeatureConfig.isGloballyEnabled();
- if (!featureEnabled) {
- if (DEBUG_LOGGING) {
- Slog.d(TAG, "filtering disabled; skipped");
- }
- return false;
- }
- if (callingSetting == null) {
- Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
- return true;
- }
- final PackageStateInternal callingPkgSetting;
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
- }
- final ArraySet<PackageStateInternal> callingSharedPkgSettings = new ArraySet<>();
-
- if (callingSetting instanceof PackageStateInternal) {
- final PackageStateInternal packageState = (PackageStateInternal) callingSetting;
- if (packageState.hasSharedUser()) {
- callingPkgSetting = null;
- callingSharedPkgSettings.addAll(getSharedUserPackages(
- packageState.getSharedUserAppId(), snapshot.getAllSharedUsers()));
-
- } else {
- callingPkgSetting = packageState;
- }
- } else {
- callingPkgSetting = null;
- callingSharedPkgSettings.addAll(
- ((SharedUserSetting) callingSetting).getPackageStates());
- }
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- if (callingPkgSetting != null) {
- if (callingPkgSetting.getPkg() != null
- && !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "DISABLED");
- }
- return false;
- }
- } else {
- for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
- final AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg();
- if (pkg != null && !mFeatureConfig.packageIsEnabled(pkg)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "DISABLED");
- }
- return false;
- }
- }
- }
-
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "getAppId");
- }
- final int callingAppId;
- if (callingPkgSetting != null) {
- callingAppId = callingPkgSetting.getAppId();
- } else {
- // all should be the same
- callingAppId = callingSharedPkgSettings.valueAt(0).getAppId();
- }
- final int targetAppId = targetPkgSetting.getAppId();
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- if (callingAppId == targetAppId) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "same app id");
- }
- return false;
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "requestsQueryAllPackages");
- }
- if (callingPkgSetting != null) {
- if (callingPkgSetting.getPkg() != null
- && requestsQueryAllPackages(callingPkgSetting.getPkg())) {
- return false;
- }
- } else {
- for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
- AndroidPackage pkg = callingSharedPkgSettings.valueAt(i).getPkg();
- if (pkg != null && requestsQueryAllPackages(pkg)) {
- return false;
- }
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- // This package isn't technically installed and won't be written to settings, so we can
- // treat it as filtered until it's available again.
- final AndroidPackage targetPkg = targetPkgSetting.getPkg();
- if (targetPkg == null) {
- if (DEBUG_LOGGING) {
- Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null");
- }
- return true;
- }
- if (targetPkg.isStaticSharedLibrary()) {
- // not an app, this filtering takes place at a higher level
- return false;
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mForceQueryable");
- }
- synchronized (mLock) {
- if (mForceQueryable.contains(targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "force queryable");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaPackage");
- }
- synchronized (mLock) {
- if (mQueriesViaPackage.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries package");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
- }
- if (!mQueriesViaComponentRequireRecompute) {
- synchronized (mLock) {
- if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries component");
- }
- return false;
- }
- }
- } else { // mQueriesViaComponent is stale
- if (!mIsSnapshot) {
- // Only recompute mQueriesViaComponent if not in snapshot
- recomputeComponentVisibility(snapshot.getPackageStates());
- synchronized (mLock) {
- if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries component");
- }
- return false;
- }
- }
- } else {
- // Do no recompute or use mQueriesViaComponent if it's stale in snapshot
- // Since we know we are in the snapshot, no need to acquire mLock because
- // mProtectedBroadcasts will not change
- if (callingPkgSetting != null) {
- if (callingPkgSetting.getPkg() != null
- && canQueryViaComponents(callingPkgSetting.getPkg(), targetPkg,
- mProtectedBroadcasts)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries component");
- }
- return false;
- }
- } else {
- for (int i = callingSharedPkgSettings.size() - 1; i >= 0; i--) {
- final AndroidPackage pkg =
- callingSharedPkgSettings.valueAt(i).getPkg();
- if (pkg != null && canQueryViaComponents(pkg, targetPkg,
- mProtectedBroadcasts)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queries component");
- }
- return false;
- }
- }
- }
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mImplicitlyQueryable");
- }
- final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
- synchronized (mLock) {
- if (mImplicitlyQueryable.contains(callingUid, targetUid)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "implicitly queryable for user");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mRetainedImplicitlyQueryable");
- }
- final int targetUid = UserHandle.getUid(targetUserId, targetAppId);
- synchronized (mLock) {
- if (mRetainedImplicitlyQueryable.contains(callingUid, targetUid)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting,
- "retained implicitly queryable for user");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mOverlayReferenceMapper");
- }
- final String targetName = targetPkg.getPackageName();
- if (!callingSharedPkgSettings.isEmpty()) {
- int size = callingSharedPkgSettings.size();
- for (int index = 0; index < size; index++) {
- PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(index);
- if (mOverlayReferenceMapper.isValidActor(targetName,
- pkgSetting.getPackageName())) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting,
- "matches shared user of package that acts on target of "
- + "overlay");
- }
- return false;
- }
- }
- } else {
- if (mOverlayReferenceMapper.isValidActor(targetName,
- callingPkgSetting.getPackageName())) {
- if (DEBUG_LOGGING) {
- log(callingPkgSetting, targetPkgSetting, "acts on target of overlay");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- try {
- if (DEBUG_TRACING) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
- }
- synchronized (mLock) {
- if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
- if (DEBUG_LOGGING) {
- log(callingSetting, targetPkgSetting, "queryable for library users");
- }
- return false;
- }
- }
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
-
- return true;
- } finally {
- if (DEBUG_TRACING) {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
- }
- }
-
- /**
- * See {@link AppsFilterSnapshot#canQueryPackage(AndroidPackage, String)}
- */
- @Override
- public boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) {
- int appId = UserHandle.getAppId(querying.getUid());
- if (appId < Process.FIRST_APPLICATION_UID) {
- return true;
- }
-
- // Check if FILTER_APPLICATION_QUERY is enabled on the given package.
- if (!mFeatureConfig.packageIsEnabled(querying)) {
- return true;
- }
-
- if (requestsQueryAllPackages(querying)) {
- return true;
- }
-
- return !querying.getQueriesPackages().isEmpty()
- && querying.getQueriesPackages().contains(potentialTarget);
- }
-
- private static boolean requestsQueryAllPackages(@NonNull AndroidPackage pkg) {
- // we're not guaranteed to have permissions yet analyzed at package add, so we inspect the
- // package directly
- return pkg.getRequestedPermissions().contains(
- Manifest.permission.QUERY_ALL_PACKAGES);
- }
-
/** Returns {@code true} if the source package instruments the target package. */
private static boolean pkgInstruments(
@NonNull AndroidPackage source, @NonNull AndroidPackage target) {
@@ -1774,117 +989,4 @@
}
}
}
-
- private static void log(Object callingSetting, PackageStateInternal targetPkgSetting,
- String description) {
- Slog.i(TAG,
- "interaction: " + (callingSetting == null ? "system" : callingSetting) + " -> "
- + targetPkgSetting + " " + description);
- }
-
- /**
- * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[],
- * QuadFunction)}
- */
- @Override
- public void dumpQueries(
- PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, int[] users,
- QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid) {
- final SparseArray<String> cache = new SparseArray<>();
- ToString<Integer> expandPackages = input -> {
- String cachedValue = cache.get(input);
- if (cachedValue == null) {
- final int callingUid = Binder.getCallingUid();
- final int appId = UserHandle.getAppId(input);
- String[] packagesForUid = null;
- for (int i = 0, size = users.length; packagesForUid == null && i < size; i++) {
- packagesForUid = getPackagesForUid.apply(callingUid, users[i], appId,
- false /*isCallerInstantApp*/);
- }
- if (packagesForUid == null) {
- cachedValue = "[app id " + input + " not installed]";
- } else {
- cachedValue = packagesForUid.length == 1 ? packagesForUid[0]
- : "[" + TextUtils.join(",", packagesForUid) + "]";
- }
- cache.put(input, cachedValue);
- }
- return cachedValue;
- };
- pw.println();
- pw.println("Queries:");
- dumpState.onTitlePrinted();
- if (!mFeatureConfig.isGloballyEnabled()) {
- pw.println(" DISABLED");
- if (!DEBUG_LOGGING) {
- return;
- }
- }
- pw.println(" system apps queryable: " + mSystemAppsQueryable);
- dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(),
- "forceQueryable", " ", expandPackages);
- synchronized (mLock) {
- pw.println(" queries via package name:");
- dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages);
- pw.println(" queries via component:");
- dumpQueriesMap(pw, filteringAppId, mQueriesViaComponent, " ", expandPackages);
- pw.println(" queryable via interaction:");
- for (int user : users) {
- pw.append(" User ").append(Integer.toString(user)).println(":");
- dumpQueriesMap(pw,
- filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
- mImplicitlyQueryable, " ", expandPackages);
- dumpQueriesMap(pw,
- filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
- mRetainedImplicitlyQueryable, " ", expandPackages);
- }
- pw.println(" queryable via uses-library:");
- dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ",
- expandPackages);
- }
- }
-
- private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
- WatchedSparseSetArray<Integer> queriesMap, String spacing,
- @Nullable ToString<Integer> toString) {
- for (int i = 0; i < queriesMap.size(); i++) {
- Integer callingId = queriesMap.keyAt(i);
- if (Objects.equals(callingId, filteringId)) {
- // don't filter target package names if the calling is filteringId
- dumpPackageSet(
- pw, null /*filteringId*/, queriesMap.get(callingId),
- toString == null
- ? callingId.toString()
- : toString.toString(callingId),
- spacing, toString);
- } else {
- dumpPackageSet(
- pw, filteringId, queriesMap.get(callingId),
- toString == null
- ? callingId.toString()
- : toString.toString(callingId),
- spacing, toString);
- }
- }
- }
-
- private interface ToString<T> {
- String toString(T input);
-
- }
-
- private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId,
- ArraySet<T> targetPkgSet, String subTitle, String spacing,
- @Nullable ToString<T> toString) {
- if (targetPkgSet != null && targetPkgSet.size() > 0
- && (filteringId == null || targetPkgSet.contains(filteringId))) {
- pw.append(spacing).append(subTitle).println(":");
- for (T item : targetPkgSet) {
- if (filteringId == null || Objects.equals(filteringId, item)) {
- pw.append(spacing).append(" ")
- .println(toString == null ? item : toString.toString(item));
- }
- }
- }
- }
}
diff --git a/services/core/java/com/android/server/pm/AppsFilterLocked.java b/services/core/java/com/android/server/pm/AppsFilterLocked.java
new file mode 100644
index 0000000..e8e6cd9
--- /dev/null
+++ b/services/core/java/com/android/server/pm/AppsFilterLocked.java
@@ -0,0 +1,93 @@
+/*
+ * 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.annotation.Nullable;
+
+import java.io.PrintWriter;
+
+/**
+ * Overrides the unlocked methods in {@link AppsFilterBase} and guards them with locks.
+ * These are used by {@link AppsFilterImpl} which contains modifications to the class members
+ */
+abstract class AppsFilterLocked extends AppsFilterBase {
+ /**
+ * Guards the accesses for the list/set class members
+ */
+ protected final Object mLock = new Object();
+ /**
+ * Guards the access for {@link AppsFilterBase#mShouldFilterCache};
+ */
+ protected Object mCacheLock = new Object();
+
+ @Override
+ protected boolean isForceQueryable(int appId) {
+ synchronized (mLock) {
+ return super.isForceQueryable(appId);
+ }
+ }
+
+ @Override
+ protected boolean isQueryableViaPackage(int callingAppId, int targetAppId) {
+ synchronized (mLock) {
+ return super.isQueryableViaPackage(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
+ protected boolean isQueryableViaComponent(int callingAppId, int targetAppId) {
+ synchronized (mLock) {
+ return super.isQueryableViaComponent(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
+ protected boolean isImplicitlyQueryable(int callingAppId, int targetAppId) {
+ synchronized (mLock) {
+ return super.isImplicitlyQueryable(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
+ protected boolean isRetainedImplicitlyQueryable(int callingAppId, int targetAppId) {
+ synchronized (mLock) {
+ return super.isRetainedImplicitlyQueryable(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
+ protected boolean isQueryableViaUsesLibrary(int callingAppId, int targetAppId) {
+ synchronized (mLock) {
+ return super.isQueryableViaUsesLibrary(callingAppId, targetAppId);
+ }
+ }
+
+ @Override
+ protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
+ synchronized (mCacheLock) {
+ return super.shouldFilterApplicationUsingCache(callingUid, appId, userId);
+ }
+ }
+
+ @Override
+ protected void dumpQueryables(PrintWriter pw, @Nullable Integer filteringAppId, int[] users,
+ ToString<Integer> expandPackages) {
+ synchronized (mLock) {
+ dumpQueryables(pw, filteringAppId, users, expandPackages);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
new file mode 100644
index 0000000..c12aa6d
--- /dev/null
+++ b/services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java
@@ -0,0 +1,60 @@
+/*
+ * 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 com.android.server.utils.SnapshotCache;
+
+import java.util.Arrays;
+
+/**
+ * Implements the copy-constructor that generates a snapshot of AppsFilter
+ */
+public final class AppsFilterSnapshotImpl extends AppsFilterBase {
+ AppsFilterSnapshotImpl(AppsFilterImpl orig) {
+ synchronized (orig.mLock) {
+ mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot();
+ mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>();
+ mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot();
+ mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>();
+ mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot();
+ mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>();
+ mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot();
+ mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>();
+ mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
+ mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
+ mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
+ mForceQueryableSnapshot = new SnapshotCache.Sealed<>();
+ mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot();
+ mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>();
+ }
+ mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
+ mForceQueryableByDevicePackageNames =
+ Arrays.copyOf(orig.mForceQueryableByDevicePackageNames,
+ orig.mForceQueryableByDevicePackageNames.length);
+ mSystemAppsQueryable = orig.mSystemAppsQueryable;
+ mFeatureConfig = orig.mFeatureConfig.snapshot();
+ mOverlayReferenceMapper = orig.mOverlayReferenceMapper;
+ mSystemSigningDetails = orig.mSystemSigningDetails;
+ synchronized (orig.mCacheLock) {
+ mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot();
+ mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>();
+ }
+
+ mBackgroundExecutor = null;
+ mSystemReady = orig.mSystemReady;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilterUtils.java b/services/core/java/com/android/server/pm/AppsFilterUtils.java
new file mode 100644
index 0000000..3a105c0
--- /dev/null
+++ b/services/core/java/com/android/server/pm/AppsFilterUtils.java
@@ -0,0 +1,172 @@
+/*
+ * 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.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.component.ParsedComponent;
+import com.android.server.pm.pkg.component.ParsedIntentInfo;
+import com.android.server.pm.pkg.component.ParsedMainComponent;
+import com.android.server.pm.pkg.component.ParsedProvider;
+import com.android.server.utils.WatchedArrayList;
+
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+final class AppsFilterUtils {
+ public static boolean requestsQueryAllPackages(@NonNull AndroidPackage pkg) {
+ // we're not guaranteed to have permissions yet analyzed at package add, so we inspect the
+ // package directly
+ return pkg.getRequestedPermissions().contains(
+ Manifest.permission.QUERY_ALL_PACKAGES);
+ }
+
+ /** Returns true if the querying package may query for the potential target package */
+ public static boolean canQueryViaComponents(AndroidPackage querying,
+ AndroidPackage potentialTarget, WatchedArrayList<String> protectedBroadcasts) {
+ if (!querying.getQueriesIntents().isEmpty()) {
+ for (Intent intent : querying.getQueriesIntents()) {
+ if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) {
+ return true;
+ }
+ }
+ }
+ if (!querying.getQueriesProviders().isEmpty()
+ && matchesProviders(querying.getQueriesProviders(), potentialTarget)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean canQueryViaPackage(AndroidPackage querying,
+ AndroidPackage potentialTarget) {
+ return !querying.getQueriesPackages().isEmpty()
+ && querying.getQueriesPackages().contains(potentialTarget.getPackageName());
+ }
+
+ public static boolean canQueryAsInstaller(PackageStateInternal querying,
+ AndroidPackage potentialTarget) {
+ final InstallSource installSource = querying.getInstallSource();
+ if (potentialTarget.getPackageName().equals(installSource.installerPackageName)) {
+ return true;
+ }
+ if (!installSource.isInitiatingPackageUninstalled
+ && potentialTarget.getPackageName().equals(installSource.initiatingPackageName)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean canQueryViaUsesLibrary(AndroidPackage querying,
+ AndroidPackage potentialTarget) {
+ if (potentialTarget.getLibraryNames().isEmpty()) {
+ return false;
+ }
+ final List<String> libNames = potentialTarget.getLibraryNames();
+ for (int i = 0, size = libNames.size(); i < size; i++) {
+ final String libName = libNames.get(i);
+ if (querying.getUsesLibraries().contains(libName)
+ || querying.getUsesOptionalLibraries().contains(libName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean matchesProviders(
+ Set<String> queriesAuthorities, AndroidPackage potentialTarget) {
+ for (int p = ArrayUtils.size(potentialTarget.getProviders()) - 1; p >= 0; p--) {
+ ParsedProvider provider = potentialTarget.getProviders().get(p);
+ if (!provider.isExported()) {
+ continue;
+ }
+ if (provider.getAuthority() == null) {
+ continue;
+ }
+ StringTokenizer authorities = new StringTokenizer(provider.getAuthority(), ";",
+ false);
+ while (authorities.hasMoreElements()) {
+ if (queriesAuthorities.contains(authorities.nextToken())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget,
+ WatchedArrayList<String> protectedBroadcasts) {
+ if (matchesAnyComponents(
+ intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) {
+ return true;
+ }
+ if (matchesAnyComponents(
+ intent, potentialTarget.getActivities(), null /*protectedBroadcasts*/)) {
+ return true;
+ }
+ if (matchesAnyComponents(intent, potentialTarget.getReceivers(), protectedBroadcasts)) {
+ return true;
+ }
+ if (matchesAnyComponents(
+ intent, potentialTarget.getProviders(), null /*protectedBroadcasts*/)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean matchesAnyComponents(Intent intent,
+ List<? extends ParsedMainComponent> components,
+ WatchedArrayList<String> protectedBroadcasts) {
+ for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) {
+ ParsedMainComponent component = components.get(i);
+ if (!component.isExported()) {
+ continue;
+ }
+ if (matchesAnyFilter(intent, component, protectedBroadcasts)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean matchesAnyFilter(Intent intent, ParsedComponent component,
+ WatchedArrayList<String> protectedBroadcasts) {
+ List<ParsedIntentInfo> intents = component.getIntents();
+ for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) {
+ IntentFilter intentFilter = intents.get(i).getIntentFilter();
+ if (matchesIntentFilter(intent, intentFilter, protectedBroadcasts)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter,
+ @Nullable WatchedArrayList<String> protectedBroadcasts) {
+ return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
+ intent.getData(), intent.getCategories(), "AppsFilter", true,
+ protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 89f8be2..daac7c0 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -236,13 +236,6 @@
verifyActivityCanHandleIntent(launchIntent, callingUid, userId);
- // Always show the cross profile animation
- if (options == null) {
- options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle();
- } else {
- options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle());
- }
-
mInjector.getActivityTaskManagerInternal()
.startActivityAsUser(
caller,
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 8c33dd9..f1296e0 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -29,7 +29,9 @@
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
import static com.android.server.pm.PackageManagerServiceUtils.REMOVE_IF_NULL_PKG;
+import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.content.Intent;
@@ -42,6 +44,7 @@
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
@@ -250,10 +253,60 @@
numberOfPackagesFailed};
}
+ /**
+ * Checks if system UI package (typically "com.android.systemui") needs to be re-compiled, and
+ * compiles it if needed.
+ */
+ private void checkAndDexOptSystemUi() {
+ Computer snapshot = mPm.snapshotComputer();
+ String sysUiPackageName =
+ mPm.mContext.getString(com.android.internal.R.string.config_systemUi);
+ AndroidPackage pkg = snapshot.getPackage(sysUiPackageName);
+ if (pkg == null) {
+ Log.w(TAG, "System UI package " + sysUiPackageName + " is not found for dexopting");
+ return;
+ }
+
+ boolean useProfileForDexopt = false;
+ File profileFile = new File(getPrebuildProfilePath(pkg));
+ // Copy the profile to the reference profile path if it exists. Installd can only use a
+ // profile at the reference profile path for dexopt.
+ if (profileFile.exists()) {
+ try {
+ synchronized (mPm.mInstallLock) {
+ if (mPm.mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
+ pkg.getUid(), pkg.getPackageName(),
+ ArtManager.getProfileName(null))) {
+ useProfileForDexopt = true;
+ } else {
+ Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath());
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath(), e);
+ }
+ }
+
+ // It could also be after mainline update, but we're not introducing a new reason just for
+ // this special case.
+ performDexOptTraced(new DexoptOptions(pkg.getPackageName(), REASON_BOOT_AFTER_OTA,
+ useProfileForDexopt ? "speed-profile" : "speed", null /* splitName */,
+ 0 /* dexoptFlags */));
+ }
+
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
public void performPackageDexOptUpgradeIfNeeded() {
PackageManagerServiceUtils.enforceSystemOrRoot(
"Only the system can request package update");
+ // The default is "true".
+ if (!"false".equals(DeviceConfig.getProperty("runtime", "dexopt_system_ui_on_boot"))) {
+ // System UI is important to user experience, so we check it on every boot. It may need
+ // to be re-compiled after a mainline update or an OTA.
+ // TODO(b/227310505): Only do this after a mainline update or an OTA.
+ checkAndDexOptSystemUi();
+ }
+
// We need to re-extract after an OTA.
boolean causeUpgrade = mPm.isDeviceUpgrading();
diff --git a/services/core/java/com/android/server/pm/FeatureConfig.java b/services/core/java/com/android/server/pm/FeatureConfig.java
new file mode 100644
index 0000000..6e356de
--- /dev/null
+++ b/services/core/java/com/android/server/pm/FeatureConfig.java
@@ -0,0 +1,56 @@
+/*
+ * 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 static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+
+@VisibleForTesting(visibility = PRIVATE)
+interface FeatureConfig {
+
+ /** Called when the system is ready and components can be queried. */
+ void onSystemReady();
+
+ /** @return true if we should filter apps at all. */
+ boolean isGloballyEnabled();
+
+ /** @return true if the feature is enabled for the given package. */
+ boolean packageIsEnabled(AndroidPackage pkg);
+
+ /** @return true if debug logging is enabled for the given package. */
+ boolean isLoggingEnabled(int appId);
+
+ /**
+ * Turns on logging for the given appId
+ *
+ * @param enable true if logging should be enabled, false if disabled.
+ */
+ void enableLogging(int appId, boolean enable);
+
+ /**
+ * Initializes the package enablement state for the given package. This gives opportunity
+ * to do any expensive operations ahead of the actual checks.
+ *
+ * @param removed true if adding, false if removing
+ */
+ void updatePackageState(PackageStateInternal setting, boolean removed);
+
+ FeatureConfig snapshot();
+}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 320b06f..32f0f10 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -119,7 +119,7 @@
IInstalld.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
private final boolean mIsolated;
-
+ private volatile boolean mDeferSetFirstBoot;
private volatile IInstalld mInstalld;
private volatile Object mWarnIfHeld;
@@ -171,6 +171,7 @@
mInstalld = IInstalld.Stub.asInterface(binder);
try {
invalidateMounts();
+ executeDeferredActions();
} catch (InstallerException ignored) {
}
} else {
@@ -180,6 +181,15 @@
}
/**
+ * Perform any deferred actions on mInstalld while the connection could not be made.
+ */
+ private void executeDeferredActions() throws InstallerException {
+ if (mDeferSetFirstBoot) {
+ setFirstBoot();
+ }
+ }
+
+ /**
* Do several pre-flight checks before making a remote call.
*
* @return if the remote call should continue.
@@ -291,8 +301,15 @@
return;
}
try {
- mInstalld.setFirstBoot();
- } catch (RemoteException e) {
+ // mInstalld might be null if the connection could not be established.
+ if (mInstalld != null) {
+ mInstalld.setFirstBoot();
+ } else {
+ // if it is null while trying to set the first boot, set a flag to try and set the
+ // first boot when the connection is eventually established
+ mDeferSetFirstBoot = true;
+ }
+ } catch (Exception e) {
throw InstallerException.from(e);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index e406a1a..a01942d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1034,7 +1034,16 @@
}
if (!SELinux.restorecon(stageDir)) {
- throw new IOException("Failed to restorecon session dir: " + stageDir);
+ String path = stageDir.getCanonicalPath();
+ String ctx = SELinux.fileSelabelLookup(path);
+ boolean success = SELinux.setFileContext(path, ctx);
+ Slog.e(TAG,
+ "Failed to SELinux.restorecon session dir, path: [" + path + "], ctx: [" + ctx
+ + "]. Retrying via SELinux.fileSelabelLookup/SELinux.setFileContext: "
+ + (success ? "SUCCESS" : "FAILURE"));
+ if (!success) {
+ throw new IOException("Failed to restorecon session dir: " + stageDir);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index ba4d09f..6400502 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4579,7 +4579,7 @@
pw.print(" (override=true)");
}
pw.println();
- if (ps.getPkg().getQueriesPackages().isEmpty()) {
+ if (!ps.getPkg().getQueriesPackages().isEmpty()) {
pw.append(prefix).append(" queriesPackages=")
.println(ps.getPkg().getQueriesPackages());
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index fef6ce1..fa0c6c3 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -166,18 +166,19 @@
* An in-memory copy of shortcuts for this package that was loaded from xml, keyed on IDs.
*/
@GuardedBy("mLock")
- final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
+ private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
/**
* A temporary copy of shortcuts that are to be cleared once persisted into AppSearch, keyed on
* IDs.
*/
@GuardedBy("mLock")
- private ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0);
+ private final ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0);
/**
* All the share targets from the package
*/
+ @GuardedBy("mLock")
private final ArrayList<ShareTargetInfo> mShareTargets = new ArrayList<>(0);
/**
@@ -231,7 +232,9 @@
}
public int getShortcutCount() {
- return mShortcuts.size();
+ synchronized (mLock) {
+ return mShortcuts.size();
+ }
}
@Override
@@ -272,7 +275,9 @@
@Nullable
public ShortcutInfo findShortcutById(@Nullable final String id) {
if (id == null) return null;
- return mShortcuts.get(id);
+ synchronized (mLock) {
+ return mShortcuts.get(id);
+ }
}
public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
@@ -347,11 +352,14 @@
* Delete a shortcut by ID. This will *always* remove it even if it's immutable or invisible.
*/
private ShortcutInfo forceDeleteShortcutInner(@NonNull String id) {
- final ShortcutInfo shortcut = mShortcuts.remove(id);
- if (shortcut != null) {
- mShortcutUser.mService.removeIconLocked(shortcut);
- shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
- | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL);
+ final ShortcutInfo shortcut;
+ synchronized (mLock) {
+ shortcut = mShortcuts.remove(id);
+ if (shortcut != null) {
+ removeIcon(shortcut);
+ shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
+ | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CACHED_ALL);
+ }
}
return shortcut;
}
@@ -366,7 +374,7 @@
forceDeleteShortcutInner(newShortcut.getId());
// Extract Icon and update the icon res ID and the bitmap path.
- s.saveIconAndFixUpShortcutLocked(newShortcut);
+ s.saveIconAndFixUpShortcutLocked(this, newShortcut);
s.fixUpShortcutResourceNamesAndValues(newShortcut);
saveShortcut(newShortcut);
}
@@ -524,14 +532,16 @@
public List<ShortcutInfo> deleteAllDynamicShortcuts() {
final long now = mShortcutUser.mService.injectCurrentTimeMillis();
boolean changed = false;
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- ShortcutInfo si = mShortcuts.valueAt(i);
- if (si.isDynamic() && si.isVisibleToPublisher()) {
- changed = true;
+ synchronized (mLock) {
+ for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+ ShortcutInfo si = mShortcuts.valueAt(i);
+ if (si.isDynamic() && si.isVisibleToPublisher()) {
+ changed = true;
- si.setTimestamp(now);
- si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
- si.setRank(0); // It may still be pinned, so clear the rank.
+ si.setTimestamp(now);
+ si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
+ si.setRank(0); // It may still be pinned, so clear the rank.
+ }
}
}
removeAllShortcutsAsync();
@@ -874,59 +884,63 @@
*/
public List<ShortcutManager.ShareShortcutInfo> getMatchingShareTargets(
@NonNull IntentFilter filter) {
- final List<ShareTargetInfo> matchedTargets = new ArrayList<>();
- for (int i = 0; i < mShareTargets.size(); i++) {
- final ShareTargetInfo target = mShareTargets.get(i);
- for (ShareTargetInfo.TargetData data : target.mTargetData) {
- if (filter.hasDataType(data.mMimeType)) {
- // Matched at least with one data type
- matchedTargets.add(target);
- break;
- }
- }
- }
-
- if (matchedTargets.isEmpty()) {
- return new ArrayList<>();
- }
-
- // Get the list of all dynamic shortcuts in this package.
- final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- // Pass callingLauncher to ensure pinned flag marked by system ui, e.g. ShareSheet, are
- // included in the result
- findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
- ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION,
- mShortcutUser.mService.mContext.getPackageName(),
- 0, /*getPinnedByAnyLauncher=*/ false);
-
- final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
- for (int i = 0; i < shortcuts.size(); i++) {
- final Set<String> categories = shortcuts.get(i).getCategories();
- if (categories == null || categories.isEmpty()) {
- continue;
- }
- for (int j = 0; j < matchedTargets.size(); j++) {
- // Shortcut must have all of share target categories
- boolean hasAllCategories = true;
- final ShareTargetInfo target = matchedTargets.get(j);
- for (int q = 0; q < target.mCategories.length; q++) {
- if (!categories.contains(target.mCategories[q])) {
- hasAllCategories = false;
+ synchronized (mLock) {
+ final List<ShareTargetInfo> matchedTargets = new ArrayList<>();
+ for (int i = 0; i < mShareTargets.size(); i++) {
+ final ShareTargetInfo target = mShareTargets.get(i);
+ for (ShareTargetInfo.TargetData data : target.mTargetData) {
+ if (filter.hasDataType(data.mMimeType)) {
+ // Matched at least with one data type
+ matchedTargets.add(target);
break;
}
}
- if (hasAllCategories) {
- result.add(new ShortcutManager.ShareShortcutInfo(shortcuts.get(i),
- new ComponentName(getPackageName(), target.mTargetClass)));
- break;
+ }
+
+ if (matchedTargets.isEmpty()) {
+ return new ArrayList<>();
+ }
+
+ // Get the list of all dynamic shortcuts in this package.
+ final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+ // Pass callingLauncher to ensure pinned flag marked by system ui, e.g. ShareSheet, are
+ // included in the result
+ findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
+ ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION,
+ mShortcutUser.mService.mContext.getPackageName(),
+ 0, /*getPinnedByAnyLauncher=*/ false);
+
+ final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
+ for (int i = 0; i < shortcuts.size(); i++) {
+ final Set<String> categories = shortcuts.get(i).getCategories();
+ if (categories == null || categories.isEmpty()) {
+ continue;
+ }
+ for (int j = 0; j < matchedTargets.size(); j++) {
+ // Shortcut must have all of share target categories
+ boolean hasAllCategories = true;
+ final ShareTargetInfo target = matchedTargets.get(j);
+ for (int q = 0; q < target.mCategories.length; q++) {
+ if (!categories.contains(target.mCategories[q])) {
+ hasAllCategories = false;
+ break;
+ }
+ }
+ if (hasAllCategories) {
+ result.add(new ShortcutManager.ShareShortcutInfo(shortcuts.get(i),
+ new ComponentName(getPackageName(), target.mTargetClass)));
+ break;
+ }
}
}
+ return result;
}
- return result;
}
public boolean hasShareTargets() {
- return !mShareTargets.isEmpty();
+ synchronized (mLock) {
+ return !mShareTargets.isEmpty();
+ }
}
/**
@@ -935,44 +949,47 @@
* the app's Xml resource.
*/
int getSharingShortcutCount() {
- if (mShareTargets.isEmpty()) {
- return 0;
- }
-
- // Get the list of all dynamic shortcuts in this package
- final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
- ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
-
- int sharingShortcutCount = 0;
- for (int i = 0; i < shortcuts.size(); i++) {
- final Set<String> categories = shortcuts.get(i).getCategories();
- if (categories == null || categories.isEmpty()) {
- continue;
+ synchronized (mLock) {
+ if (mShareTargets.isEmpty()) {
+ return 0;
}
- for (int j = 0; j < mShareTargets.size(); j++) {
- // A SharingShortcut must have all of share target categories
- boolean hasAllCategories = true;
- final ShareTargetInfo target = mShareTargets.get(j);
- for (int q = 0; q < target.mCategories.length; q++) {
- if (!categories.contains(target.mCategories[q])) {
- hasAllCategories = false;
+
+ // Get the list of all dynamic shortcuts in this package
+ final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+ findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
+ ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+
+ int sharingShortcutCount = 0;
+ for (int i = 0; i < shortcuts.size(); i++) {
+ final Set<String> categories = shortcuts.get(i).getCategories();
+ if (categories == null || categories.isEmpty()) {
+ continue;
+ }
+ for (int j = 0; j < mShareTargets.size(); j++) {
+ // A SharingShortcut must have all of share target categories
+ boolean hasAllCategories = true;
+ final ShareTargetInfo target = mShareTargets.get(j);
+ for (int q = 0; q < target.mCategories.length; q++) {
+ if (!categories.contains(target.mCategories[q])) {
+ hasAllCategories = false;
+ break;
+ }
+ }
+ if (hasAllCategories) {
+ sharingShortcutCount++;
break;
}
}
- if (hasAllCategories) {
- sharingShortcutCount++;
- break;
- }
}
+ return sharingShortcutCount;
}
- return sharingShortcutCount;
}
/**
* Return the filenames (excluding path names) of icon bitmap files from this package.
*/
- public ArraySet<String> getUsedBitmapFiles() {
+ @GuardedBy("mLock")
+ private ArraySet<String> getUsedBitmapFilesLocked() {
final ArraySet<String> usedFiles = new ArraySet<>(1);
forEachShortcut(si -> {
if (si.getBitmapPath() != null) {
@@ -982,6 +999,26 @@
return usedFiles;
}
+ public void cleanupDanglingBitmapFiles(@NonNull File path) {
+ synchronized (mLock) {
+ mShortcutBitmapSaver.waitForAllSavesLocked();
+ final ArraySet<String> usedFiles = getUsedBitmapFilesLocked();
+
+ for (File child : path.listFiles()) {
+ if (!child.isFile()) {
+ continue;
+ }
+ final String name = child.getName();
+ if (!usedFiles.contains(name)) {
+ if (ShortcutService.DEBUG) {
+ Slog.d(TAG, "Removing dangling bitmap file: " + child.getAbsolutePath());
+ }
+ child.delete();
+ }
+ }
+ }
+ }
+
private static String getFileName(@NonNull String path) {
final int sep = path.lastIndexOf(File.separatorChar);
if (sep == -1) {
@@ -1069,19 +1106,25 @@
// Now prepare to publish manifest shortcuts.
List<ShortcutInfo> newManifestShortcutList = null;
- try {
- newManifestShortcutList = ShortcutParser.parseShortcuts(mShortcutUser.mService,
- getPackageName(), getPackageUserId(), mShareTargets);
- } catch (IOException|XmlPullParserException e) {
- Slog.e(TAG, "Failed to load shortcuts from AndroidManifest.xml.", e);
+ final int shareTargetSize;
+ synchronized (mLock) {
+ try {
+ shareTargetSize = mShareTargets.size();
+ newManifestShortcutList = ShortcutParser.parseShortcuts(mShortcutUser.mService,
+ getPackageName(), getPackageUserId(), mShareTargets);
+ } catch (IOException | XmlPullParserException e) {
+ Slog.e(TAG, "Failed to load shortcuts from AndroidManifest.xml.", e);
+ }
}
final int manifestShortcutSize = newManifestShortcutList == null ? 0
: newManifestShortcutList.size();
if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) {
Slog.d(TAG,
- String.format("Package %s has %d manifest shortcut(s), and %d share target(s)",
- getPackageName(), manifestShortcutSize, mShareTargets.size()));
+ String.format(
+ "Package %s has %d manifest shortcut(s), and %d share target(s)",
+ getPackageName(), manifestShortcutSize, shareTargetSize));
}
+
if (isNewApp && (manifestShortcutSize == 0)) {
// If it's a new app, and it doesn't have manifest shortcuts, then nothing to do.
@@ -1608,6 +1651,11 @@
pw.print(" (");
pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize[0]));
pw.println(")");
+
+ pw.println();
+ synchronized (mLock) {
+ mShortcutBitmapSaver.dumpLocked(pw, " ");
+ }
}
public void dumpShortcuts(@NonNull PrintWriter pw, int matchFlags) {
@@ -1675,37 +1723,38 @@
@Override
public void saveToXml(@NonNull TypedXmlSerializer out, boolean forBackup)
throws IOException, XmlPullParserException {
- final int size = mShortcuts.size();
- final int shareTargetSize = mShareTargets.size();
+ synchronized (mLock) {
+ final int size = mShortcuts.size();
+ final int shareTargetSize = mShareTargets.size();
- if (hasNoShortcut() && shareTargetSize == 0 && mApiCallCount == 0) {
- return; // nothing to write.
- }
+ if (hasNoShortcut() && shareTargetSize == 0 && mApiCallCount == 0) {
+ return; // nothing to write.
+ }
- out.startTag(null, TAG_ROOT);
+ out.startTag(null, TAG_ROOT);
- ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
- ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
- ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
- if (!forBackup) {
- synchronized (mLock) {
- ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, (mIsAppSearchSchemaUpToDate)
+ ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
+ ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
+ ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
+ if (!forBackup) {
+ ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, mIsAppSearchSchemaUpToDate
? AppSearchShortcutInfo.SCHEMA_VERSION : 0);
}
- }
- getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
+ getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
- for (int j = 0; j < size; j++) {
- saveShortcut(out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed());
- }
-
- if (!forBackup) {
- for (int j = 0; j < shareTargetSize; j++) {
- mShareTargets.get(j).saveToXml(out);
+ for (int j = 0; j < size; j++) {
+ saveShortcut(
+ out, mShortcuts.valueAt(j), forBackup, getPackageInfo().isBackupAllowed());
}
- }
- out.endTag(null, TAG_ROOT);
+ if (!forBackup) {
+ for (int j = 0; j < shareTargetSize; j++) {
+ mShareTargets.get(j).saveToXml(out);
+ }
+ }
+
+ out.endTag(null, TAG_ROOT);
+ }
}
private void saveShortcut(TypedXmlSerializer out, ShortcutInfo si, boolean forBackup,
@@ -1729,7 +1778,7 @@
// Note: at this point no shortcuts should have bitmaps pending save, but if they do,
// just remove the bitmap.
if (si.isIconPendingSave()) {
- s.removeIconLocked(si);
+ removeIcon(si);
}
out.startTag(null, TAG_SHORTCUT);
ShortcutService.writeAttr(out, ATTR_ID, si.getId());
@@ -1891,38 +1940,38 @@
synchronized (ret.mLock) {
ret.mIsAppSearchSchemaUpToDate = ShortcutService.parseIntAttribute(
parser, ATTR_SCHEMA_VERSON, 0) == AppSearchShortcutInfo.SCHEMA_VERSION;
- }
- ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
- ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);
+ ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
+ ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);
- final int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- final int depth = parser.getDepth();
- final String tag = parser.getName();
- if (depth == outerDepth + 1) {
- switch (tag) {
- case ShortcutPackageInfo.TAG_ROOT:
- ret.getPackageInfo().loadFromXml(parser, fromBackup);
-
- continue;
- case TAG_SHORTCUT:
- final ShortcutInfo si = parseShortcut(parser, packageName,
- shortcutUser.getUserId(), fromBackup);
- // Don't use addShortcut(), we don't need to save the icon.
- ret.mShortcuts.put(si.getId(), si);
- continue;
- case TAG_SHARE_TARGET:
- ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
- continue;
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
}
+ final int depth = parser.getDepth();
+ final String tag = parser.getName();
+ if (depth == outerDepth + 1) {
+ switch (tag) {
+ case ShortcutPackageInfo.TAG_ROOT:
+ ret.getPackageInfo().loadFromXml(parser, fromBackup);
+
+ continue;
+ case TAG_SHORTCUT:
+ final ShortcutInfo si = parseShortcut(parser, packageName,
+ shortcutUser.getUserId(), fromBackup);
+ // Don't use addShortcut(), we don't need to save the icon.
+ ret.mShortcuts.put(si.getId(), si);
+ continue;
+ case TAG_SHARE_TARGET:
+ ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
+ continue;
+ }
+ }
+ ShortcutService.warnForInvalidTag(depth, tag);
}
- ShortcutService.warnForInvalidTag(depth, tag);
}
return ret;
}
@@ -2126,7 +2175,9 @@
@VisibleForTesting
List<ShareTargetInfo> getAllShareTargetsForTest() {
- return new ArrayList<>(mShareTargets);
+ synchronized (mLock) {
+ return new ArrayList<>(mShareTargets);
+ }
}
@Override
@@ -2265,15 +2316,19 @@
private void saveShortcut(@NonNull final Collection<ShortcutInfo> shortcuts) {
Objects.requireNonNull(shortcuts);
- for (ShortcutInfo si : shortcuts) {
- mShortcuts.put(si.getId(), si);
+ synchronized (mLock) {
+ for (ShortcutInfo si : shortcuts) {
+ mShortcuts.put(si.getId(), si);
+ }
}
}
@Nullable
List<ShortcutInfo> findAll(@NonNull final Collection<String> ids) {
- return ids.stream().map(mShortcuts::get)
- .filter(Objects::nonNull).collect(Collectors.toList());
+ synchronized (mLock) {
+ return ids.stream().map(mShortcuts::get)
+ .filter(Objects::nonNull).collect(Collectors.toList());
+ }
}
private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) {
@@ -2292,10 +2347,12 @@
private void forEachShortcutStopWhen(
@NonNull final Function<ShortcutInfo, Boolean> cb) {
- for (int i = mShortcuts.size() - 1; i >= 0; i--) {
- final ShortcutInfo si = mShortcuts.valueAt(i);
- if (cb.apply(si)) {
- return;
+ synchronized (mLock) {
+ for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+ final ShortcutInfo si = mShortcuts.valueAt(i);
+ if (cb.apply(si)) {
+ return;
+ }
}
}
}
@@ -2435,6 +2492,7 @@
})));
}
+ @GuardedBy("mLock")
@Override
void scheduleSaveToAppSearchLocked() {
final Map<String, ShortcutInfo> copy = new ArrayMap<>(mShortcuts);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index 6e0436f..7800183 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -16,8 +16,10 @@
package com.android.server.pm;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
+import android.graphics.Bitmap;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.TypedXmlSerializer;
@@ -50,6 +52,9 @@
protected ShortcutUser mShortcutUser;
+ @GuardedBy("mLock")
+ protected ShortcutBitmapSaver mShortcutBitmapSaver;
+
protected final Object mLock = new Object();
protected ShortcutPackageItem(@NonNull ShortcutUser shortcutUser,
@@ -59,6 +64,7 @@
mPackageUserId = packageUserId;
mPackageName = Preconditions.checkStringNotEmpty(packageName);
mPackageInfo = Objects.requireNonNull(packageInfo);
+ mShortcutBitmapSaver = new ShortcutBitmapSaver(shortcutUser.mService);
}
/**
@@ -206,7 +212,7 @@
void saveShortcutPackageItem() {
// Wait for bitmap saves to conclude before proceeding to saving shortcuts.
- mShortcutUser.mService.waitForBitmapSaves();
+ waitForBitmapSaves();
// Save each ShortcutPackageItem in a separate Xml file.
final File path = getShortcutPackageItemFile();
if (ShortcutService.DEBUG || ShortcutService.DEBUG_REBOOT) {
@@ -221,6 +227,35 @@
}
}
+ public boolean waitForBitmapSaves() {
+ synchronized (mLock) {
+ return mShortcutBitmapSaver.waitForAllSavesLocked();
+ }
+ }
+
+ public void saveBitmap(ShortcutInfo shortcut,
+ int maxDimension, Bitmap.CompressFormat format, int quality) {
+ synchronized (mLock) {
+ mShortcutBitmapSaver.saveBitmapLocked(shortcut, maxDimension, format, quality);
+ }
+ }
+
+ /**
+ * Wait for all pending saves to finish, and then return the given shortcut's bitmap path.
+ */
+ @Nullable
+ public String getBitmapPathMayWait(ShortcutInfo shortcut) {
+ synchronized (mLock) {
+ return mShortcutBitmapSaver.getBitmapPathMayWaitLocked(shortcut);
+ }
+ }
+
+ public void removeIcon(ShortcutInfo shortcut) {
+ synchronized (mLock) {
+ mShortcutBitmapSaver.removeIcon(shortcut);
+ }
+ }
+
void removeShortcutPackageItem() {
synchronized (mLock) {
getShortcutPackageItemFile().delete();
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 780f976..f2bcf5e 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -363,7 +363,6 @@
private final RoleManager mRoleManager;
private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
- private final ShortcutBitmapSaver mShortcutBitmapSaver;
private final ShortcutDumpFiles mShortcutDumpFiles;
@GuardedBy("mLock")
@@ -490,7 +489,6 @@
mRoleManager = Objects.requireNonNull(mContext.getSystemService(RoleManager.class));
mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
- mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
mShortcutDumpFiles = new ShortcutDumpFiles(this);
mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, true)
@@ -1063,8 +1061,6 @@
Slog.d(TAG, "Saving to " + path);
}
- mShortcutBitmapSaver.waitForAllSavesLocked();
-
path.getParentFile().mkdirs();
final AtomicFile file = new AtomicFile(path);
FileOutputStream os = null;
@@ -1388,15 +1384,12 @@
// === Caller validation ===
- void removeIconLocked(ShortcutInfo shortcut) {
- mShortcutBitmapSaver.removeIcon(shortcut);
- }
-
public void cleanupBitmapsForPackage(@UserIdInt int userId, String packageName) {
final File packagePath = new File(getUserBitmapFilePath(userId), packageName);
if (!packagePath.isDirectory()) {
return;
}
+ // ShortcutPackage is already removed at this point, we can safely remove the folder.
if (!(FileUtils.deleteContents(packagePath) && packagePath.delete())) {
Slog.w(TAG, "Unable to remove directory " + packagePath);
}
@@ -1437,38 +1430,12 @@
}
cleanupBitmapsForPackage(userId, packageName);
} else {
- cleanupDanglingBitmapFilesLocked(userId, user, packageName, child);
+ user.getPackageShortcuts(packageName).cleanupDanglingBitmapFiles(child);
}
}
logDurationStat(Stats.CLEANUP_DANGLING_BITMAPS, start);
}
- /**
- * Remove dangling bitmap files for a package.
- *
- * Note this method must be called with the lock held after calling
- * {@link ShortcutBitmapSaver#waitForAllSavesLocked()} to make sure there's no pending bitmap
- * saves are going on.
- */
- private void cleanupDanglingBitmapFilesLocked(@UserIdInt int userId, @NonNull ShortcutUser user,
- @NonNull String packageName, @NonNull File path) {
- final ArraySet<String> usedFiles =
- user.getPackageShortcuts(packageName).getUsedBitmapFiles();
-
- for (File child : path.listFiles()) {
- if (!child.isFile()) {
- continue;
- }
- final String name = child.getName();
- if (!usedFiles.contains(name)) {
- if (DEBUG) {
- Slog.d(TAG, "Removing dangling bitmap file: " + child.getAbsolutePath());
- }
- child.delete();
- }
- }
- }
-
@VisibleForTesting
static class FileOutputStreamWithPath extends FileOutputStream {
private final File mFile;
@@ -1513,7 +1480,7 @@
}
}
- void saveIconAndFixUpShortcutLocked(ShortcutInfo shortcut) {
+ void saveIconAndFixUpShortcutLocked(ShortcutPackage p, ShortcutInfo shortcut) {
if (shortcut.hasIconFile() || shortcut.hasIconResource() || shortcut.hasIconUri()) {
return;
}
@@ -1521,7 +1488,7 @@
final long token = injectClearCallingIdentity();
try {
// Clear icon info on the shortcut.
- removeIconLocked(shortcut);
+ p.removeIcon(shortcut);
final Icon icon = shortcut.getIcon();
if (icon == null) {
@@ -1560,8 +1527,7 @@
// just in case.
throw ShortcutInfo.getInvalidIconException();
}
- mShortcutBitmapSaver.saveBitmapLocked(shortcut,
- maxIconDimension, mIconPersistFormat, mIconPersistQuality);
+ p.saveBitmap(shortcut, maxIconDimension, mIconPersistFormat, mIconPersistQuality);
} finally {
// Once saved, we won't use the original icon information, so null it out.
shortcut.clearIcon();
@@ -2110,7 +2076,7 @@
final boolean replacingIcon = (source.getIcon() != null);
if (replacingIcon) {
- removeIconLocked(target);
+ ps.removeIcon(target);
}
// Note copyNonNullFieldsFrom() does the "updatable with?" check too.
@@ -2118,7 +2084,7 @@
target.setTimestamp(injectCurrentTimeMillis());
if (replacingIcon) {
- saveIconAndFixUpShortcutLocked(target);
+ saveIconAndFixUpShortcutLocked(ps, target);
}
// When we're updating any resource related fields, re-extract the res
@@ -3463,7 +3429,7 @@
if (shortcutInfo == null) {
return null;
}
- return getShortcutIconParcelFileDescriptor(shortcutInfo);
+ return getShortcutIconParcelFileDescriptor(p, shortcutInfo);
}
}
@@ -3476,6 +3442,7 @@
Objects.requireNonNull(shortcutId, "shortcutId");
// Checks shortcuts in memory first
+ final ShortcutPackage p;
synchronized (mLock) {
throwIfUserLockedL(userId);
throwIfUserLockedL(launcherUserId);
@@ -3483,8 +3450,7 @@
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
- final ShortcutPackage p = getUserShortcutsLocked(userId)
- .getPackageShortcutsIfExists(packageName);
+ p = getUserShortcutsLocked(userId).getPackageShortcutsIfExists(packageName);
if (p == null) {
cb.complete(null);
return;
@@ -3492,24 +3458,23 @@
final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
if (shortcutInfo != null) {
- cb.complete(getShortcutIconParcelFileDescriptor(shortcutInfo));
+ cb.complete(getShortcutIconParcelFileDescriptor(p, shortcutInfo));
return;
}
}
// Otherwise check persisted shortcuts
- getShortcutInfoAsync(launcherUserId, packageName, shortcutId, userId, si -> {
- cb.complete(getShortcutIconParcelFileDescriptor(si));
- });
+ getShortcutInfoAsync(launcherUserId, packageName, shortcutId, userId, si ->
+ cb.complete(getShortcutIconParcelFileDescriptor(p, si)));
}
@Nullable
private ParcelFileDescriptor getShortcutIconParcelFileDescriptor(
- @Nullable final ShortcutInfo shortcutInfo) {
- if (shortcutInfo == null || !shortcutInfo.hasIconFile()) {
+ @Nullable final ShortcutPackage p, @Nullable final ShortcutInfo shortcutInfo) {
+ if (p == null || shortcutInfo == null || !shortcutInfo.hasIconFile()) {
return null;
}
- final String path = mShortcutBitmapSaver.getBitmapPathMayWaitLocked(shortcutInfo);
+ final String path = p.getBitmapPathMayWait(shortcutInfo);
if (path == null) {
Slog.w(TAG, "null bitmap detected in getShortcutIconFd()");
return null;
@@ -4772,9 +4737,6 @@
}
pw.println();
- mShortcutBitmapSaver.dumpLocked(pw, " ");
-
- pw.println();
}
for (int i = 0; i < mUsers.size(); i++) {
@@ -5347,9 +5309,11 @@
}
}
- void waitForBitmapSaves() {
+ @VisibleForTesting
+ void waitForBitmapSavesForTest() {
synchronized (mLock) {
- mShortcutBitmapSaver.waitForAllSavesLocked();
+ forEachLoadedUserLocked(u ->
+ u.forAllPackageItems(ShortcutPackageItem::waitForBitmapSaves));
}
}
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 75e18b5..b9fd2fd 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -401,6 +401,7 @@
private void saveShortcutPackageItem(TypedXmlSerializer out, ShortcutPackageItem spi,
boolean forBackup) throws IOException, XmlPullParserException {
+ spi.waitForBitmapSaves();
if (forBackup) {
if (spi.getPackageUserId() != spi.getOwnerUserId()) {
return; // Don't save cross-user information.
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 0dabff8..bcdf429 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1430,6 +1430,8 @@
/**
* Returns a UserInfo object with the name filled in, for Owner and Guest, or the original
* if the name is already set.
+ *
+ * Note: Currently, the resulting name can be null if a user was truly created with a null name.
*/
private UserInfo userWithName(UserInfo orig) {
if (orig != null && orig.name == null) {
@@ -1638,7 +1640,7 @@
}
@Override
- public String getUserName() {
+ public @NonNull String getUserName() {
final int callingUid = Binder.getCallingUid();
if (!hasQueryOrCreateUsersPermission()
&& !hasPermissionGranted(
@@ -1649,7 +1651,10 @@
final int userId = UserHandle.getUserId(callingUid);
synchronized (mUsersLock) {
UserInfo userInfo = userWithName(getUserInfoLU(userId));
- return userInfo == null ? "" : userInfo.name;
+ if (userInfo != null && userInfo.name != null) {
+ return userInfo.name;
+ }
+ return "";
}
}
@@ -4165,7 +4170,7 @@
* @return the converted user, or {@code null} if no pre-created user could be converted.
*/
private @Nullable UserInfo convertPreCreatedUserIfPossible(String userType,
- @UserInfoFlag int flags, String name, @Nullable Object token) {
+ @UserInfoFlag int flags, @Nullable String name, @Nullable Object token) {
final UserData preCreatedUserData;
synchronized (mUsersLock) {
preCreatedUserData = getPreCreatedUserLU(userType);
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 2277d8a..7be83b0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2816,14 +2816,12 @@
}
// Remove review flag as it is not necessary anymore
- // TODO(b/227186603) re-enable check for notification permission once
- // droidfood state has been cleared
- //if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
+ if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
wasChanged = true;
}
- //}
+ }
if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0
&& !isPermissionSplitFromNonRuntime(permName,
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index e1ff9ea..6ee9c66 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -392,6 +392,9 @@
if ((flags & PARSE_FRAMEWORK_RES_SPLITS) != 0) {
liteParseFlags = flags;
}
+ if ((flags & PARSE_APK_IN_APEX) != 0) {
+ liteParseFlags |= PARSE_APK_IN_APEX;
+ }
final ParseResult<PackageLite> liteResult =
ApkLiteParseUtils.parseClusterPackageLite(input, packageDir, frameworkSplits,
liteParseFlags);
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 7ba1cad..977f79f 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -1453,16 +1453,6 @@
}
}
- try {
- if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, UserHandle.USER_SYSTEM)
- == 0) {
- return false;
- }
- } catch (Settings.SettingNotFoundException e) {
- return false;
- }
-
if (!pkg.getRequestedPermissions().contains(POST_NOTIFICATIONS)
|| CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, pkgName, user)
|| mKeyguardManager.isKeyguardLocked()) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b142141..d8e7fbe 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -27,7 +27,6 @@
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.O;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
@@ -130,7 +129,6 @@
import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.session.MediaSessionLegacyHelper;
-import android.os.BatteryManagerInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.DeviceIdleManager;
@@ -396,7 +394,6 @@
PowerManagerInternal mPowerManagerInternal;
IStatusBarService mStatusBarService;
StatusBarManagerInternal mStatusBarManagerInternal;
- BatteryManagerInternal mBatteryManagerInternal;
AudioManagerInternal mAudioManagerInternal;
DisplayManager mDisplayManager;
DisplayManagerInternal mDisplayManagerInternal;
@@ -791,8 +788,7 @@
@Override
public void onWakeUp() {
synchronized (mLock) {
- if (shouldEnableWakeGestureLp()
- && getBatteryManagerInternal().getPlugType() != BATTERY_PLUGGED_WIRELESS) {
+ if (shouldEnableWakeGestureLp()) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
"Wake Up");
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
@@ -849,15 +845,6 @@
}
}
- BatteryManagerInternal getBatteryManagerInternal() {
- synchronized (mServiceAcquireLock) {
- if (mBatteryManagerInternal == null) {
- mBatteryManagerInternal =
- LocalServices.getService(BatteryManagerInternal.class);
- }
- return mBatteryManagerInternal;
- }
- }
// returns true if the key was handled and should not be passed to the user
private boolean backKeyPress() {
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyController.java b/services/core/java/com/android/server/power/LowPowerStandbyController.java
index 2d2bad2..5964fa4 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyController.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyController.java
@@ -68,7 +68,7 @@
*
* @hide
*/
-public final class LowPowerStandbyController {
+public class LowPowerStandbyController {
private static final String TAG = "LowPowerStandbyController";
private static final boolean DEBUG = false;
private static final boolean DEFAULT_ACTIVE_DURING_MAINTENANCE = false;
@@ -173,7 +173,9 @@
mSettingsObserver = new SettingsObserver(mHandler);
}
- void systemReady() {
+ /** Call when system services are ready */
+ @VisibleForTesting
+ public void systemReady() {
final Resources resources = mContext.getResources();
synchronized (mLock) {
mSupportedConfig = resources.getBoolean(
@@ -435,7 +437,9 @@
}
}
- void setActiveDuringMaintenance(boolean activeDuringMaintenance) {
+ /** Set whether Low Power Standby should be active during doze maintenance mode. */
+ @VisibleForTesting
+ public void setActiveDuringMaintenance(boolean activeDuringMaintenance) {
synchronized (mLock) {
if (!mSupportedConfig) {
Slog.w(TAG, "Low Power Standby settings cannot be changed "
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 0834417..3c779f3 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -727,7 +727,8 @@
return false;
}
- if (mKeyguardManager != null && mKeyguardManager.isDeviceLocked(userId)) {
+ if (requiresAuthentication() && mKeyguardManager != null
+ && mKeyguardManager.isDeviceLocked(userId)) {
Log.i(TAG, "Can't change mic/cam toggle while device is locked");
return false;
}
@@ -993,6 +994,13 @@
}
@Override
+ public boolean requiresAuthentication() {
+ enforceObserveSensorPrivacyPermission();
+ return mContext.getResources()
+ .getBoolean(R.bool.config_sensorPrivacyRequiresAuthentication);
+ }
+
+ @Override
public void showSensorUseDialog(int sensor) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Can only be called by the system uid");
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index b685572..d48f263 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1650,13 +1650,11 @@
}
@Override
- public void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed,
- boolean isBubbleSuppressed) {
+ public void onBubbleMetadataFlagChanged(String key, int flags) {
enforceStatusBarService();
final long identity = Binder.clearCallingIdentity();
try {
- mNotificationDelegate.onBubbleNotificationSuppressionChanged(key, isNotifSuppressed,
- isBubbleSuppressed);
+ mNotificationDelegate.onBubbleMetadataFlagChanged(key, flags);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index d374814..4b8c7c1 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -122,16 +122,9 @@
if (!TrustManagerService.ENABLE_ACTIVE_UNLOCK_FLAG) {
return;
}
- if (!mWaitingForTrustableDowngrade) {
- return;
- }
// are these the broadcasts we want to listen to
- if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())
- || Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
- mTrusted = false;
- mTrustable = true;
- mWaitingForTrustableDowngrade = false;
- mTrustManagerService.updateTrust(mUserId, 0);
+ if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+ downgradeToTrustable();
}
}
};
@@ -480,8 +473,7 @@
final String pathUri = mAlarmIntent.toUri(Intent.URI_INTENT_SCHEME);
alarmFilter.addDataPath(pathUri, PatternMatcher.PATTERN_LITERAL);
- IntentFilter trustableFilter = new IntentFilter(Intent.ACTION_USER_PRESENT);
- trustableFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ IntentFilter trustableFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
// Schedules a restart for when connecting times out. If the connection succeeds,
// the restart is canceled in mCallback's onConnected.
@@ -668,6 +660,19 @@
mTrustable = false;
}
+ /**
+ * Downgrades the trustagent to trustable as a result of a keyguard or screen related event, and
+ * then updates the trust state of the phone to reflect the change.
+ */
+ public void downgradeToTrustable() {
+ if (mWaitingForTrustableDowngrade) {
+ mWaitingForTrustableDowngrade = false;
+ mTrusted = false;
+ mTrustable = true;
+ mTrustManagerService.updateTrust(mUserId, 0);
+ }
+ }
+
public boolean isManagingTrust() {
return mManagingTrust && !mTrustDisabledByDpm;
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 8f4ddea..80ce70d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1184,6 +1184,22 @@
return false;
}
+ /**
+ * We downgrade to trustable whenever keyguard changes its showing value.
+ * - becomes showing: something has caused the device to show keyguard which happens due to
+ * user intent to lock the device either through direct action or a timeout
+ * - becomes not showing: keyguard was dismissed and we no longer need to keep the device
+ * unlocked
+ * */
+ private void dispatchTrustableDowngrade() {
+ for (int i = 0; i < mActiveAgents.size(); i++) {
+ AgentInfo info = mActiveAgents.valueAt(i);
+ if (info.userId == mCurrentUser) {
+ info.agent.downgradeToTrustable();
+ }
+ }
+ }
+
private List<String> getTrustGrantedMessages(int userId) {
if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
return new ArrayList<>();
@@ -1752,6 +1768,7 @@
refreshDeviceLockedForUser(UserHandle.USER_ALL);
break;
case MSG_KEYGUARD_SHOWING_CHANGED:
+ dispatchTrustableDowngrade();
refreshDeviceLockedForUser(mCurrentUser);
break;
case MSG_START_USER:
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index ee30fa2..fb9a4d4 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -15,6 +15,8 @@
*/
package com.android.server.tv.tunerresourcemanager;
+import android.media.tv.tunerresourcemanager.TunerResourceManager;
+
import java.util.HashSet;
import java.util.Set;
@@ -63,6 +65,11 @@
private int mNiceValue;
/**
+ * The handle of the primary frontend resource
+ */
+ private int mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
+
+ /**
* List of the frontend handles that are used by the current client.
*/
private Set<Integer> mUsingFrontendHandles = new HashSet<>();
@@ -175,6 +182,22 @@
}
/**
+ * Set the primary frontend used by the client
+ *
+ * @param frontendHandle being used.
+ */
+ public void setPrimaryFrontend(int frontendHandle) {
+ mPrimaryUsingFrontendHandle = frontendHandle;
+ }
+
+ /**
+ * Get the primary frontend used by the client
+ */
+ public int getPrimaryFrontend() {
+ return mPrimaryUsingFrontendHandle;
+ }
+
+ /**
* Update the set of client that share frontend with the current client.
*
* @param clientId the client to share the fe with the current client.
@@ -206,6 +229,7 @@
public void releaseFrontend() {
mUsingFrontendHandles.clear();
mShareFeClientIds.clear();
+ mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
}
/**
@@ -276,6 +300,7 @@
public void reclaimAllResources() {
mUsingFrontendHandles.clear();
mShareFeClientIds.clear();
+ mPrimaryUsingFrontendHandle = TunerResourceManager.INVALID_RESOURCE_HANDLE;
mUsingLnbHandles.clear();
mUsingCasSystemId = INVALID_RESOURCE_ID;
mUsingCiCamId = INVALID_RESOURCE_ID;
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index af705d5..6162d716 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -42,6 +42,7 @@
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -72,14 +73,28 @@
private static final long INVALID_THREAD_ID = -1;
private static final long TRMS_LOCK_TIMEOUT = 500;
+ private static final int INVALID_FE_COUNT = -1;
+
// Map of the registered client profiles
private Map<Integer, ClientProfile> mClientProfiles = new HashMap<>();
private int mNextUnusedClientId = 0;
// Map of the current available frontend resources
private Map<Integer, FrontendResource> mFrontendResources = new HashMap<>();
- // Backup Map of the current available frontend resources
+ // SparseIntArray of the max usable number for each frontend resource type
+ private SparseIntArray mFrontendMaxUsableNums = new SparseIntArray();
+ // SparseIntArray of the currently used number for each frontend resource type
+ private SparseIntArray mFrontendUsedNums = new SparseIntArray();
+ // SparseIntArray of the existing number for each frontend resource type
+ private SparseIntArray mFrontendExistingNums = new SparseIntArray();
+
+ // Backups for the frontend resource maps for enabling testing with custom resource maps
+ // such as TunerTest.testHasUnusedFrontend1()
private Map<Integer, FrontendResource> mFrontendResourcesBackup = new HashMap<>();
+ private SparseIntArray mFrontendMaxUsableNumsBackup = new SparseIntArray();
+ private SparseIntArray mFrontendUsedNumsBackup = new SparseIntArray();
+ private SparseIntArray mFrontendExistingNumsBackup = new SparseIntArray();
+
// Map of the current available lnb resources
private Map<Integer, LnbResource> mLnbResources = new HashMap<>();
// Map of the current available Cas resources
@@ -268,6 +283,29 @@
}
@Override
+ public boolean setMaxNumberOfFrontends(int frontendType, int maxUsableNum) {
+ enforceTunerAccessPermission("requestFrontend");
+ enforceTrmAccessPermission("requestFrontend");
+ if (maxUsableNum < 0) {
+ Slog.w(TAG, "setMaxNumberOfFrontends failed with maxUsableNum:" + maxUsableNum
+ + " frontendType:" + frontendType);
+ return false;
+ }
+ synchronized (mLock) {
+ return setMaxNumberOfFrontendsInternal(frontendType, maxUsableNum);
+ }
+ }
+
+ @Override
+ public int getMaxNumberOfFrontends(int frontendType) {
+ enforceTunerAccessPermission("requestFrontend");
+ enforceTrmAccessPermission("requestFrontend");
+ synchronized (mLock) {
+ return getMaxNumberOfFrontendsInternal(frontendType);
+ }
+ }
+
+ @Override
public void shareFrontend(int selfClientId, int targetClientId) throws RemoteException {
enforceTunerAccessPermission("shareFrontend");
enforceTrmAccessPermission("shareFrontend");
@@ -572,71 +610,19 @@
}
synchronized (mLock) {
- if (mClientProfiles != null) {
- pw.println("ClientProfiles:");
- pw.increaseIndent();
- for (Map.Entry<Integer, ClientProfile> entry : mClientProfiles.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mFrontendResources != null) {
- pw.println("FrontendResources:");
- pw.increaseIndent();
- for (Map.Entry<Integer, FrontendResource> entry
- : mFrontendResources.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mFrontendResourcesBackup != null) {
- pw.println("FrontendResourcesBackUp:");
- pw.increaseIndent();
- for (Map.Entry<Integer, FrontendResource> entry
- : mFrontendResourcesBackup.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mLnbResources != null) {
- pw.println("LnbResources:");
- pw.increaseIndent();
- for (Map.Entry<Integer, LnbResource> entry : mLnbResources.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mCasResources != null) {
- pw.println("CasResources:");
- pw.increaseIndent();
- for (Map.Entry<Integer, CasResource> entry : mCasResources.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mCiCamResources != null) {
- pw.println("CiCamResources:");
- pw.increaseIndent();
- for (Map.Entry<Integer, CiCamResource> entry : mCiCamResources.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
-
- if (mListeners != null) {
- pw.println("Listners:");
- pw.increaseIndent();
- for (Map.Entry<Integer, ResourcesReclaimListenerRecord> entry
- : mListeners.entrySet()) {
- pw.println(entry.getKey() + " : " + entry.getValue());
- }
- pw.decreaseIndent();
- }
+ dumpMap(mClientProfiles, "ClientProfiles:", "\n", pw);
+ dumpMap(mFrontendResources, "FrontendResources:", "\n", pw);
+ dumpSIA(mFrontendExistingNums, "FrontendExistingNums:", ", ", pw);
+ dumpSIA(mFrontendUsedNums, "FrontendUsedNums:", ", ", pw);
+ dumpSIA(mFrontendMaxUsableNums, "FrontendMaxUsableNums:", ", ", pw);
+ dumpMap(mFrontendResourcesBackup, "FrontendResourcesBackUp:", "\n", pw);
+ dumpSIA(mFrontendExistingNumsBackup, "FrontendExistingNumsBackup:", ", ", pw);
+ dumpSIA(mFrontendUsedNumsBackup, "FrontendUsedNumsBackup:", ", ", pw);
+ dumpSIA(mFrontendMaxUsableNumsBackup, "FrontendUsedNumsBackup:", ", ", pw);
+ dumpMap(mLnbResources, "LnbResource:", "\n", pw);
+ dumpMap(mCasResources, "CasResource:", "\n", pw);
+ dumpMap(mCiCamResources, "CiCamResource:", "\n", pw);
+ dumpMap(mListeners, "Listners:", "\n", pw);
}
}
@@ -786,10 +772,10 @@
protected void storeResourceMapInternal(int resourceType) {
switch (resourceType) {
case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND:
- if (mFrontendResources != null && mFrontendResources.size() > 0) {
- mFrontendResourcesBackup.putAll(mFrontendResources);
- mFrontendResources.clear();
- }
+ replaceFeResourceMap(mFrontendResources, mFrontendResourcesBackup);
+ replaceFeCounts(mFrontendExistingNums, mFrontendExistingNumsBackup);
+ replaceFeCounts(mFrontendUsedNums, mFrontendUsedNumsBackup);
+ replaceFeCounts(mFrontendMaxUsableNums, mFrontendMaxUsableNumsBackup);
break;
// TODO: implement for other resource type when needed
default:
@@ -800,9 +786,10 @@
protected void clearResourceMapInternal(int resourceType) {
switch (resourceType) {
case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND:
- if (mFrontendResources != null) {
- mFrontendResources.clear();
- }
+ replaceFeResourceMap(null, mFrontendResources);
+ replaceFeCounts(null, mFrontendExistingNums);
+ replaceFeCounts(null, mFrontendUsedNums);
+ replaceFeCounts(null, mFrontendMaxUsableNums);
break;
// TODO: implement for other resource type when needed
default:
@@ -813,12 +800,10 @@
protected void restoreResourceMapInternal(int resourceType) {
switch (resourceType) {
case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND:
- if (mFrontendResourcesBackup != null
- && mFrontendResourcesBackup.size() > 0) {
- mFrontendResources.clear();
- mFrontendResources.putAll(mFrontendResourcesBackup);
- mFrontendResourcesBackup.clear();
- }
+ replaceFeResourceMap(mFrontendResourcesBackup, mFrontendResources);
+ replaceFeCounts(mFrontendExistingNumsBackup, mFrontendExistingNums);
+ replaceFeCounts(mFrontendUsedNumsBackup, mFrontendUsedNums);
+ replaceFeCounts(mFrontendMaxUsableNumsBackup, mFrontendMaxUsableNums);
break;
// TODO: implement for other resource type when needed
default:
@@ -954,6 +939,11 @@
for (FrontendResource fr : getFrontendResources().values()) {
if (fr.getType() == request.frontendType) {
if (!fr.isInUse()) {
+ // Unused resource cannot be acquired if the max is already reached, but
+ // TRM still has to look for the reclaim candidate
+ if (isFrontendMaxNumUseReached(request.frontendType)) {
+ continue;
+ }
// Grant unused frontend with no exclusive group members first.
if (fr.getExclusiveGroupMemberFeHandles().isEmpty()) {
grantingFrontendHandle = fr.getHandle();
@@ -1021,6 +1011,9 @@
for (int inUseHandle : newOwnerProfile.getInUseFrontendHandles()) {
getFrontendResource(inUseHandle).setOwner(newOwnerId);
}
+ // change the primary frontend
+ newOwnerProfile.setPrimaryFrontend(currentOwnerProfile.getPrimaryFrontend());
+ currentOwnerProfile.setPrimaryFrontend(TunerResourceManager.INVALID_RESOURCE_HANDLE);
// double check there is no other resources tied to the previous owner
for (int inUseHandle : currentOwnerProfile.getInUseFrontendHandles()) {
int ownerId = getFrontendResource(inUseHandle).getOwnerClientId();
@@ -1657,11 +1650,13 @@
FrontendResource grantingFrontend = getFrontendResource(grantingHandle);
ClientProfile ownerProfile = getClientProfile(ownerClientId);
grantingFrontend.setOwner(ownerClientId);
+ increFrontendNum(mFrontendUsedNums, grantingFrontend.getType());
ownerProfile.useFrontend(grantingHandle);
for (int exclusiveGroupMember : grantingFrontend.getExclusiveGroupMemberFeHandles()) {
getFrontendResource(exclusiveGroupMember).setOwner(ownerClientId);
ownerProfile.useFrontend(exclusiveGroupMember);
}
+ ownerProfile.setPrimaryFrontend(grantingHandle);
}
private void updateLnbClientMappingOnNewGrant(int grantingHandle, int ownerClientId) {
@@ -1755,6 +1750,109 @@
return mFrontendResources;
}
+ private boolean setMaxNumberOfFrontendsInternal(int frontendType, int maxUsableNum) {
+ int usedNum = mFrontendUsedNums.get(frontendType, INVALID_FE_COUNT);
+ if (usedNum == INVALID_FE_COUNT || usedNum <= maxUsableNum) {
+ mFrontendMaxUsableNums.put(frontendType, maxUsableNum);
+ return true;
+ } else {
+ Slog.e(TAG, "max number of frontend for frontendType: " + frontendType
+ + " cannot be set to a value lower than the current usage count."
+ + " (requested max num = " + maxUsableNum + ", current usage = " + usedNum);
+ return false;
+ }
+ }
+
+ private int getMaxNumberOfFrontendsInternal(int frontendType) {
+ int existingNum = mFrontendExistingNums.get(frontendType, INVALID_FE_COUNT);
+ if (existingNum == INVALID_FE_COUNT) {
+ Log.e(TAG, "existingNum is -1 for " + frontendType);
+ return -1;
+ }
+ int maxUsableNum = mFrontendMaxUsableNums.get(frontendType, INVALID_FE_COUNT);
+ if (maxUsableNum == INVALID_FE_COUNT) {
+ return existingNum;
+ } else {
+ return maxUsableNum;
+ }
+ }
+
+ private boolean isFrontendMaxNumUseReached(int frontendType) {
+ int maxUsableNum = mFrontendMaxUsableNums.get(frontendType, INVALID_FE_COUNT);
+ if (maxUsableNum == INVALID_FE_COUNT) {
+ return false;
+ }
+ int useNum = mFrontendUsedNums.get(frontendType, INVALID_FE_COUNT);
+ if (useNum == INVALID_FE_COUNT) {
+ useNum = 0;
+ }
+ return useNum >= maxUsableNum;
+ }
+
+ private void increFrontendNum(SparseIntArray targetNums, int frontendType) {
+ int num = targetNums.get(frontendType, INVALID_FE_COUNT);
+ if (num == INVALID_FE_COUNT) {
+ targetNums.put(frontendType, 1);
+ } else {
+ targetNums.put(frontendType, num + 1);
+ }
+ }
+
+ private void decreFrontendNum(SparseIntArray targetNums, int frontendType) {
+ int num = targetNums.get(frontendType, INVALID_FE_COUNT);
+ if (num != INVALID_FE_COUNT) {
+ targetNums.put(frontendType, num - 1);
+ }
+ }
+
+ private void replaceFeResourceMap(Map<Integer, FrontendResource> srcMap, Map<Integer,
+ FrontendResource> dstMap) {
+ if (dstMap != null) {
+ dstMap.clear();
+ if (srcMap != null && srcMap.size() > 0) {
+ dstMap.putAll(srcMap);
+ }
+ }
+ }
+
+ private void replaceFeCounts(SparseIntArray srcCounts, SparseIntArray dstCounts) {
+ if (dstCounts != null) {
+ dstCounts.clear();
+ if (srcCounts != null) {
+ for (int i = 0; i < srcCounts.size(); i++) {
+ dstCounts.put(srcCounts.keyAt(i), srcCounts.valueAt(i));
+ }
+ }
+ }
+ }
+ private void dumpMap(Map<?, ?> targetMap, String headline, String delimiter,
+ IndentingPrintWriter pw) {
+ if (targetMap != null) {
+ pw.println(headline);
+ pw.increaseIndent();
+ for (Map.Entry<?, ?> entry : targetMap.entrySet()) {
+ pw.print(entry.getKey() + " : " + entry.getValue());
+ pw.print(delimiter);
+ }
+ pw.println();
+ pw.decreaseIndent();
+ }
+ }
+
+ private void dumpSIA(SparseIntArray array, String headline, String delimiter,
+ IndentingPrintWriter pw) {
+ if (array != null) {
+ pw.println(headline);
+ pw.increaseIndent();
+ for (int i = 0; i < array.size(); i++) {
+ pw.print(array.keyAt(i) + " : " + array.valueAt(i));
+ pw.print(delimiter);
+ }
+ pw.println();
+ pw.decreaseIndent();
+ }
+ }
+
private void addFrontendResource(FrontendResource newFe) {
// Update the exclusive group member list in all the existing Frontend resource
for (FrontendResource fe : getFrontendResources().values()) {
@@ -1771,6 +1869,8 @@
}
// Update resource list and available id list
mFrontendResources.put(newFe.getHandle(), newFe);
+ increFrontendNum(mFrontendExistingNums, newFe.getType());
+
}
private void removeFrontendResource(int removingHandle) {
@@ -1789,6 +1889,7 @@
getFrontendResource(excGroupmemberFeHandle)
.removeExclusiveGroupMemberFeId(fe.getHandle());
}
+ decreFrontendNum(mFrontendExistingNums, fe.getType());
mFrontendResources.remove(removingHandle);
}
@@ -1918,6 +2019,15 @@
}
}
+
+ int primaryFeId = profile.getPrimaryFrontend();
+ if (primaryFeId != TunerResourceManager.INVALID_RESOURCE_HANDLE) {
+ FrontendResource primaryFe = getFrontendResource(primaryFeId);
+ if (primaryFe != null) {
+ decreFrontendNum(mFrontendUsedNums, primaryFe.getType());
+ }
+ }
+
profile.releaseFrontend();
}
diff --git a/services/core/java/com/android/server/utils/WatchedArrayList.java b/services/core/java/com/android/server/utils/WatchedArrayList.java
index 6059f96..07474a63 100644
--- a/services/core/java/com/android/server/utils/WatchedArrayList.java
+++ b/services/core/java/com/android/server/utils/WatchedArrayList.java
@@ -416,7 +416,7 @@
dst.mStorage.ensureCapacity(end);
for (int i = 0; i < end; i++) {
final E val = Snapshots.maybeSnapshot(src.get(i));
- dst.add(i, val);
+ dst.mStorage.add(val);
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedArrayMap.java b/services/core/java/com/android/server/utils/WatchedArrayMap.java
index 7c1cde8..63441aa 100644
--- a/services/core/java/com/android/server/utils/WatchedArrayMap.java
+++ b/services/core/java/com/android/server/utils/WatchedArrayMap.java
@@ -465,7 +465,7 @@
for (int i = 0; i < end; i++) {
final V val = Snapshots.maybeSnapshot(src.valueAt(i));
final K key = src.keyAt(i);
- dst.put(key, val);
+ dst.mStorage.put(key, val);
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedArraySet.java b/services/core/java/com/android/server/utils/WatchedArraySet.java
index ec80261..a2eaed7 100644
--- a/services/core/java/com/android/server/utils/WatchedArraySet.java
+++ b/services/core/java/com/android/server/utils/WatchedArraySet.java
@@ -427,7 +427,7 @@
dst.mStorage.ensureCapacity(end);
for (int i = 0; i < end; i++) {
final E val = Snapshots.maybeSnapshot(src.valueAt(i));
- dst.append(val);
+ dst.mStorage.append(val);
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedLongSparseArray.java b/services/core/java/com/android/server/utils/WatchedLongSparseArray.java
index bf23de1..9da9e75 100644
--- a/services/core/java/com/android/server/utils/WatchedLongSparseArray.java
+++ b/services/core/java/com/android/server/utils/WatchedLongSparseArray.java
@@ -410,7 +410,7 @@
for (int i = 0; i < end; i++) {
final E val = Snapshots.maybeSnapshot(src.valueAt(i));
final long key = src.keyAt(i);
- dst.put(key, val);
+ dst.mStorage.put(key, val);
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseArray.java b/services/core/java/com/android/server/utils/WatchedSparseArray.java
index 9b99b91..6ce38b7 100644
--- a/services/core/java/com/android/server/utils/WatchedSparseArray.java
+++ b/services/core/java/com/android/server/utils/WatchedSparseArray.java
@@ -490,7 +490,7 @@
for (int i = 0; i < end; i++) {
final E val = Snapshots.maybeSnapshot(src.valueAt(i));
final int key = src.keyAt(i);
- dst.put(key, val);
+ dst.mStorage.put(key, val);
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java
index 772a8d0..50e2272 100644
--- a/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java
+++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanArray.java
@@ -310,7 +310,7 @@
}
final int end = src.size();
for (int i = 0; i < end; i++) {
- dst.put(src.keyAt(i), src.valueAt(i));
+ dst.mStorage.put(src.keyAt(i), src.valueAt(i));
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseIntArray.java b/services/core/java/com/android/server/utils/WatchedSparseIntArray.java
index 72705bf..53d1682 100644
--- a/services/core/java/com/android/server/utils/WatchedSparseIntArray.java
+++ b/services/core/java/com/android/server/utils/WatchedSparseIntArray.java
@@ -315,7 +315,7 @@
}
final int end = src.size();
for (int i = 0; i < end; i++) {
- dst.put(src.keyAt(i), src.valueAt(i));
+ dst.mStorage.put(src.keyAt(i), src.valueAt(i));
}
dst.seal();
}
diff --git a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java
index 05db12e..77750ed 100644
--- a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java
+++ b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java
@@ -169,7 +169,7 @@
final ArraySet set = src.get(i);
final int setSize = set.size();
for (int j = 0; j < setSize; j++) {
- dst.add(src.keyAt(i), set.valueAt(j));
+ dst.mStorage.add(src.keyAt(i), set.valueAt(j));
}
}
dst.seal();
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 63619e5..f1dbad61 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -446,6 +446,43 @@
// Not relevant for the window observer.
}
+ public Pair<Matrix, MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
+ IBinder token) {
+ synchronized (mService.mGlobalLock) {
+ final Matrix transformationMatrix = new Matrix();
+ final MagnificationSpec magnificationSpec = new MagnificationSpec();
+
+ final WindowState windowState = mService.mWindowMap.get(token);
+ if (windowState != null) {
+ windowState.getTransformationMatrix(new float[9], transformationMatrix);
+
+ if (hasCallbacks()) {
+ final MagnificationSpec otherMagnificationSpec =
+ getMagnificationSpecForWindow(windowState);
+ if (otherMagnificationSpec != null && !otherMagnificationSpec.isNop()) {
+ magnificationSpec.setTo(otherMagnificationSpec);
+ }
+ }
+ }
+
+ return new Pair<>(transformationMatrix, magnificationSpec);
+ }
+ }
+
+ MagnificationSpec getMagnificationSpecForWindow(WindowState windowState) {
+ if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
+ mAccessibilityTracing.logTrace(TAG + ".getMagnificationSpecForWindow",
+ FLAGS_MAGNIFICATION_CALLBACK,
+ "windowState={" + windowState + "}");
+ }
+ final int displayId = windowState.getDisplayId();
+ final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
+ if (displayMagnifier != null) {
+ return displayMagnifier.getMagnificationSpecForWindow(windowState);
+ }
+ return null;
+ }
+
boolean hasCallbacks() {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
| FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d00d8b8..791d193 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -933,9 +933,10 @@
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity pause timeout for " + ActivityRecord.this);
synchronized (mAtmService.mGlobalLock) {
- if (hasProcess()) {
- mAtmService.logAppTooSlow(app, pauseTime, "pausing " + ActivityRecord.this);
+ if (!hasProcess()) {
+ return;
}
+ mAtmService.logAppTooSlow(app, pauseTime, "pausing " + ActivityRecord.this);
activityPaused(true);
}
}
@@ -5095,7 +5096,11 @@
final boolean recentsAnimating = isAnimating(PARENTS, ANIMATION_TYPE_RECENTS);
if (okToAnimate(true /* ignoreFrozen */, canTurnScreenOn())
&& (appTransition.isTransitionSet()
- || (recentsAnimating && !isActivityTypeHome()))) {
+ || (recentsAnimating && !isActivityTypeHome()))
+ // If the visibility change during enter PIP, we don't want to include it in app
+ // transition to affect the animation theme, because the Pip organizer will animate
+ // the entering PIP instead.
+ && !mWaitForEnteringPinnedMode) {
if (visible) {
displayContent.mOpeningApps.add(this);
mEnteringAnimation = true;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 34c083a..b2f27eb 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1807,6 +1807,10 @@
// Check if starting activity on given task or on a new task is allowed.
int startResult = isAllowedToStart(r, newTask, targetTask);
if (startResult != START_SUCCESS) {
+ if (r.resultTo != null) {
+ r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
+ null /* data */, null /* dataGrants */);
+ }
return startResult;
}
@@ -1976,13 +1980,9 @@
mPreferredWindowingMode = mLaunchParams.mWindowingMode;
}
- private int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
- if (mStartActivity.packageName == null) {
- if (mStartActivity.resultTo != null) {
- mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
- mStartActivity.requestCode, RESULT_CANCELED,
- null /* data */, null /* dataGrants */);
- }
+ @VisibleForTesting
+ int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) {
+ if (r.packageName == null) {
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
@@ -2005,8 +2005,7 @@
|| !targetTask.isUidPresent(mCallingUid)
|| (LAUNCH_SINGLE_INSTANCE == mLaunchMode && targetTask.inPinnedWindowingMode()));
- if (mRestrictedBgActivity && blockBalInTask
- && handleBackgroundActivityAbort(mStartActivity)) {
+ if (mRestrictedBgActivity && blockBalInTask && handleBackgroundActivityAbort(r)) {
Slog.e(TAG, "Abort background activity starts from " + mCallingUid);
return START_ABORTED;
}
@@ -2020,12 +2019,12 @@
if (!newTask) {
if (mService.getLockTaskController().isLockTaskModeViolation(targetTask,
isNewClearTask)) {
- Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
+ Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
} else {
- if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(mStartActivity)) {
- Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
+ if (mService.getLockTaskController().isNewTaskLockTaskModeViolation(r)) {
+ Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
}
@@ -2733,8 +2732,8 @@
intentActivity.getTaskFragment().clearLastPausedActivity();
Task intentTask = intentActivity.getTask();
- // Only update the target-root-task when it is not indicated.
if (mTargetRootTask == null) {
+ // Update launch target task when it is not indicated.
if (mSourceRecord != null && mSourceRecord.mLaunchRootTask != null) {
// Inherit the target-root-task from source to ensure trampoline activities will be
// launched into the same root task.
@@ -2743,6 +2742,17 @@
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask,
mOptions);
}
+ } else {
+ // If a launch target indicated, and the matching task is already in the adjacent task
+ // of the launch target. Adjust to use the adjacent task as its launch target. So the
+ // existing task will be launched into the closer one and won't be reparent redundantly.
+ // TODO(b/231541706): Migrate the logic to wm-shell after having proper APIs to help
+ // resolve target task without actually starting the activity.
+ final Task adjacentTargetTask = mTargetRootTask.getAdjacentTaskFragment() != null
+ ? mTargetRootTask.getAdjacentTaskFragment().asTask() : null;
+ if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) {
+ mTargetRootTask = adjacentTargetTask;
+ }
}
// If the target task is not in the front, then we need to bring it to the front...
@@ -2772,7 +2782,7 @@
intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
}
- if (mTargetRootTask == intentActivity.getRootTask()) {
+ if (intentActivity.isDescendantOf(mTargetRootTask)) {
// TODO(b/151572268): Figure out a better way to move tasks in above 2-levels
// tasks hierarchies.
if (mTargetRootTask != intentTask
@@ -2819,19 +2829,6 @@
mTargetRootTask = intentActivity.getRootTask();
mSupervisor.handleNonResizableTaskIfNeeded(intentTask, WINDOWING_MODE_UNDEFINED,
mRootWindowContainer.getDefaultTaskDisplayArea(), mTargetRootTask);
-
- // We need to check if there is a launch root task in TDA for this target root task.
- // If it exist, we need to reparent target root task from TDA to launch root task.
- final TaskDisplayArea tda = mTargetRootTask.getDisplayArea();
- final Task launchRootTask = tda.getLaunchRootTask(mTargetRootTask.getWindowingMode(),
- mTargetRootTask.getActivityType(), null /** options */, mSourceRootTask,
- mLaunchFlags);
- // If target root task is created by organizer, let organizer handle reparent itself.
- if (!mTargetRootTask.mCreatedByOrganizer && launchRootTask != null
- && launchRootTask != mTargetRootTask) {
- mTargetRootTask.reparent(launchRootTask, POSITION_TOP);
- mTargetRootTask = launchRootTask;
- }
}
private void resumeTargetRootTaskIfNeeded() {
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index ee7d9a9..46ce433 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -153,10 +153,10 @@
for (WindowContainer wc : mRootMembers) {
wc.waitForSyncTransactionCommit(wcAwaitingCommit);
}
- final Runnable callback = new Runnable() {
+ class CommitCallback implements Runnable {
// Can run a second time if the action completes after the timeout.
boolean ran = false;
- public void run() {
+ public void onCommitted() {
synchronized (mWm.mGlobalLock) {
if (ran) {
return;
@@ -171,8 +171,23 @@
wcAwaitingCommit.clear();
}
}
+
+ // Called in timeout
+ @Override
+ public void run() {
+ // Sometimes we get a trace, sometimes we get a bugreport without
+ // a trace. Since these kind of ANRs can trigger such an issue,
+ // try and ensure we will have some visibility in both cases.
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionCommitTimeout");
+ Slog.e(TAG, "WM sent Transaction to organized, but never received" +
+ " commit callback. Application ANR likely to follow.");
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ onCommitted();
+
+ }
};
- merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::run);
+ CommitCallback callback = new CommitCallback();
+ merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::onCommitted);
mWm.mH.postDelayed(callback, BLAST_TIMEOUT_DURATION);
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index b37f980..247117e 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -124,8 +124,7 @@
LocalServices.getService(WindowManagerInternal.class);
IBinder focusedWindowToken = windowManagerInternal.getFocusedWindowToken();
- window = wmService.windowForClientLocked(null, focusedWindowToken,
- false /* throwOnError */);
+ window = wmService.getFocusedWindowLocked();
if (window == null) {
EmbeddedWindowController.EmbeddedWindow embeddedWindow =
@@ -147,12 +146,6 @@
}
if (window == null) {
- window = wmService.getFocusedWindowLocked();
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
- "Focused window found using wmService.getFocusedWindowLocked()");
- }
-
- if (window == null) {
// We don't have any focused window, fallback ont the top currentTask of the focused
// display.
ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
@@ -194,7 +187,6 @@
if (backType == BackNavigationInfo.TYPE_CALLBACK
|| currentActivity == null
|| currentTask == null
- || currentTask.getDisplayContent().getImeContainer().isVisible()
|| currentActivity.isActivityTypeHome()) {
return infoBuilder
.setType(backType)
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ed1bbf8..d0baa23 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2922,7 +2922,7 @@
}
DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) {
- if (mDisplayPolicy == null) {
+ if (mDisplayPolicy == null || mInitialDisplayCutout == null) {
return null;
}
return DisplayCutout.fromResourcesRectApproximation(
@@ -2931,7 +2931,7 @@
}
RoundedCorners loadRoundedCorners(int displayWidth, int displayHeight) {
- if (mDisplayPolicy == null) {
+ if (mDisplayPolicy == null || mInitialRoundedCorners == null) {
return null;
}
return RoundedCorners.fromResources(
@@ -4272,7 +4272,15 @@
setImeInputTarget(target);
mInsetsStateController.updateAboveInsetsState(mInsetsStateController
.getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
- updateImeControlTarget();
+ // Force updating the IME parent when the IME control target has been updated to the
+ // remote target but updateImeParent not happen because ImeLayeringTarget and
+ // ImeInputTarget are different. Then later updateImeParent would be ignored when there
+ // is no new IME control target to change the IME parent.
+ final boolean forceUpdateImeParent = mImeControlTarget == mRemoteInsetsControlTarget
+ && (mInputMethodSurfaceParent != null
+ && !mInputMethodSurfaceParent.isSameSurface(
+ mImeWindowsContainer.getParent().mSurfaceControl));
+ updateImeControlTarget(forceUpdateImeParent);
}
// Unfreeze IME insets after the new target updated, in case updateAboveInsetsState may
// deliver unrelated IME insets change to the non-IME requester.
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 67dd89e..33cdd2e 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -270,6 +270,22 @@
}
}
+ @Override
+ public void notifyPointerDisplayIdChanged(int displayId, float x, float y) {
+ synchronized (mService.mGlobalLock) {
+ mService.setMousePointerDisplayId(displayId);
+ if (displayId == Display.INVALID_DISPLAY) return;
+
+ final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
+ if (dc == null) {
+ Slog.wtf(TAG, "The mouse pointer was moved to display " + displayId
+ + " that does not have a valid DisplayContent.");
+ return;
+ }
+ mService.restorePointerIconLocked(dc, x, y);
+ }
+ }
+
/** Waits until the built-in input devices have been configured. */
public boolean waitForInputDevicesReady(long timeoutMillis) {
synchronized (mInputDevicesReadyMonitor) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 65062e5..ea72e12 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -573,7 +573,7 @@
recentsAnimationController.getTargetAppDisplayArea();
if (targetDA != null) {
mRecentsAnimationInputConsumer.reparent(mInputTransaction, targetDA);
- mRecentsAnimationInputConsumer.show(mInputTransaction, MAX_VALUE - 1);
+ mRecentsAnimationInputConsumer.show(mInputTransaction, MAX_VALUE - 2);
mAddRecentsAnimationInputConsumerHandle = false;
}
}
@@ -584,10 +584,14 @@
final Task rootTask = w.getTask().getRootTask();
mPipInputConsumer.mWindowHandle.replaceTouchableRegionWithCrop(
rootTask.getSurfaceControl());
+ final DisplayArea targetDA = rootTask.getDisplayArea();
// We set the layer to z=MAX-1 so that it's always on top.
- mPipInputConsumer.reparent(mInputTransaction, rootTask);
- mPipInputConsumer.show(mInputTransaction, MAX_VALUE - 1);
- mAddPipInputConsumerHandle = false;
+ if (targetDA != null) {
+ mPipInputConsumer.layout(mInputTransaction, rootTask.getBounds());
+ mPipInputConsumer.reparent(mInputTransaction, targetDA);
+ mPipInputConsumer.show(mInputTransaction, MAX_VALUE - 1);
+ mAddPipInputConsumerHandle = false;
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index efe617d..2bae59a 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -19,7 +19,6 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
@@ -602,22 +601,12 @@
|| mDisplayContent.getAsyncRotationController() != null) {
return;
}
- boolean shouldTranslateNavBar = false;
- final boolean isDisplayLandscape =
- mDisplayContent.getConfiguration().orientation == ORIENTATION_LANDSCAPE;
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
final Task task = adapter.mTask;
- final TaskFragment adjacentTask = task.getRootTask().getAdjacentTaskFragment();
- final boolean inSplitScreen = task.inSplitScreen();
- if (task.isActivityTypeHomeOrRecents()
- // Skip if the task is in split screen and in landscape.
- || (inSplitScreen && isDisplayLandscape)
- // Skip if the task is the top task in split screen.
- || (inSplitScreen && task.getBounds().top < adjacentTask.getBounds().top)) {
+ if (task.isActivityTypeHomeOrRecents()) {
continue;
}
- shouldTranslateNavBar = inSplitScreen;
mNavBarAttachedApp = task.getTopVisibleActivity();
break;
}
@@ -630,9 +619,7 @@
navWindow.mToken.cancelAnimation();
final SurfaceControl.Transaction t = navWindow.mToken.getPendingTransaction();
final SurfaceControl navSurfaceControl = navWindow.mToken.getSurfaceControl();
- if (shouldTranslateNavBar) {
- navWindow.setSurfaceTranslationY(-mNavBarAttachedApp.getBounds().top);
- }
+ navWindow.setSurfaceTranslationY(-mNavBarAttachedApp.getBounds().top);
t.reparent(navSurfaceControl, mNavBarAttachedApp.getSurfaceControl());
t.show(navSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 83be73a..c7f8a1e 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.TimeUtils.NANOS_PER_MS;
import static android.view.Choreographer.CALLBACK_TRAVERSAL;
import static android.view.Choreographer.getSfInstance;
@@ -26,14 +27,13 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
-import android.graphics.Canvas;
import android.graphics.Insets;
-import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.power.Boost;
import android.os.Handler;
import android.os.PowerManagerInternal;
+import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log;
import android.view.Choreographer;
@@ -50,6 +50,8 @@
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.function.Supplier;
/**
@@ -83,6 +85,12 @@
private final PowerManagerInternal mPowerManagerInternal;
private boolean mApplyScheduled;
+ // Executor to perform the edge extension.
+ // With two threads because in practice we will want to extend two surfaces in one animation,
+ // in which case we want to be able to parallelize those two extensions to cut down latency in
+ // starting the animation.
+ private final ExecutorService mEdgeExtensionExecutor = Executors.newFixedThreadPool(2);
+
@GuardedBy("mLock")
@VisibleForTesting
final ArrayMap<SurfaceControl, RunningAnimation> mPendingAnimations = new ArrayMap<>();
@@ -150,7 +158,7 @@
void continueStartingAnimations() {
synchronized (mLock) {
mAnimationStartDeferred = false;
- if (!mPendingAnimations.isEmpty()) {
+ if (!mPendingAnimations.isEmpty() && mPreProcessingAnimations.isEmpty()) {
mChoreographer.postFrameCallback(this::startAnimations);
}
}
@@ -173,7 +181,7 @@
// We must wait for t to be committed since otherwise the leash doesn't have the
// windows we want to screenshot and extend as children.
- t.addTransactionCommittedListener(Runnable::run, () -> {
+ t.addTransactionCommittedListener(mEdgeExtensionExecutor, () -> {
final WindowAnimationSpec animationSpec = a.asWindowAnimationSpec();
final Transaction edgeExtensionCreationTransaction = new Transaction();
@@ -196,7 +204,7 @@
mPreProcessingAnimations.remove(animationLeash);
mPendingAnimations.put(animationLeash, runningAnim);
- if (!mAnimationStartDeferred) {
+ if (!mAnimationStartDeferred && mPreProcessingAnimations.isEmpty()) {
mChoreographer.postFrameCallback(this::startAnimations);
}
}
@@ -206,7 +214,7 @@
if (!requiresEdgeExtension) {
mPendingAnimations.put(animationLeash, runningAnim);
- if (!mAnimationStartDeferred) {
+ if (!mAnimationStartDeferred && mPreProcessingAnimations.isEmpty()) {
mChoreographer.postFrameCallback(this::startAnimations);
}
@@ -322,6 +330,14 @@
private void startAnimations(long frameTimeNanos) {
synchronized (mLock) {
+ if (!mPreProcessingAnimations.isEmpty()) {
+ // We only want to start running animations once all mPreProcessingAnimations have
+ // been processed to ensure preprocessed animations start in sync.
+ // NOTE: This means we might delay running animations that require preprocessing if
+ // new animations that also require preprocessing are requested before the previous
+ // ones have finished (see b/227449117).
+ return;
+ }
startPendingAnimationsLocked();
}
mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
@@ -403,30 +419,17 @@
private void createExtensionSurface(SurfaceControl leash, Rect edgeBounds,
Rect extensionRect, int xPos, int yPos, String layerName,
Transaction startTransaction) {
- synchronized (mEdgeExtensionLock) {
- if (!mEdgeExtensions.containsKey(leash)) {
- // Animation leash has already been removed so we shouldn't perform any extension
- return;
- }
- createExtensionSurfaceLocked(leash, edgeBounds, extensionRect, xPos, yPos, layerName,
- startTransaction);
- }
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createExtensionSurface");
+ doCreateExtensionSurface(leash, edgeBounds, extensionRect, xPos, yPos, layerName,
+ startTransaction);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- private void createExtensionSurfaceLocked(SurfaceControl surfaceToExtend, Rect edgeBounds,
+ private void doCreateExtensionSurface(SurfaceControl leash, Rect edgeBounds,
Rect extensionRect, int xPos, int yPos, String layerName,
Transaction startTransaction) {
- final SurfaceControl edgeExtensionLayer = new SurfaceControl.Builder()
- .setName(layerName)
- .setParent(surfaceToExtend)
- .setHidden(true)
- .setCallsite("DefaultTransitionHandler#startAnimation")
- .setOpaque(true)
- .setBufferSize(extensionRect.width(), extensionRect.height())
- .build();
-
SurfaceControl.LayerCaptureArgs captureArgs =
- new SurfaceControl.LayerCaptureArgs.Builder(surfaceToExtend)
+ new SurfaceControl.LayerCaptureArgs.Builder(leash /* surfaceToExtend */)
.setSourceCrop(edgeBounds)
.setFrameScale(1)
.setPixelFormat(PixelFormat.RGBA_8888)
@@ -437,31 +440,76 @@
SurfaceControl.captureLayers(captureArgs);
if (edgeBuffer == null) {
+ // The leash we are trying to screenshot may have been removed by this point, which is
+ // likely the reason for ending up with a null edgeBuffer, in which case we just want to
+ // return and do nothing.
Log.e("SurfaceAnimationRunner", "Failed to create edge extension - "
+ "edge buffer is null");
return;
}
- android.graphics.BitmapShader shader =
- new android.graphics.BitmapShader(edgeBuffer.asBitmap(),
- android.graphics.Shader.TileMode.CLAMP,
- android.graphics.Shader.TileMode.CLAMP);
- final Paint paint = new Paint();
- paint.setShader(shader);
+ final SurfaceControl edgeExtensionLayer = new SurfaceControl.Builder()
+ .setName(layerName)
+ .setHidden(true)
+ .setCallsite("DefaultTransitionHandler#startAnimation")
+ .setOpaque(true)
+ .setBufferSize(edgeBounds.width(), edgeBounds.height())
+ .build();
final Surface surface = new Surface(edgeExtensionLayer);
- Canvas c = surface.lockHardwareCanvas();
- c.drawRect(extensionRect, paint);
- surface.unlockCanvasAndPost(c);
+ surface.attachAndQueueBufferWithColorSpace(edgeBuffer.getHardwareBuffer(),
+ edgeBuffer.getColorSpace());
surface.release();
- startTransaction.setLayer(edgeExtensionLayer, Integer.MIN_VALUE);
- startTransaction.setPosition(edgeExtensionLayer, xPos, yPos);
- startTransaction.setVisibility(edgeExtensionLayer, true);
+ final float scaleX = getScaleXForExtensionSurface(edgeBounds, extensionRect);
+ final float scaleY = getScaleYForExtensionSurface(edgeBounds, extensionRect);
- mEdgeExtensions.get(surfaceToExtend).add(edgeExtensionLayer);
+ synchronized (mEdgeExtensionLock) {
+ if (!mEdgeExtensions.containsKey(leash)) {
+ // The animation leash has already been removed, so we don't want to attach the
+ // edgeExtension layer and should immediately remove it instead.
+ startTransaction.remove(edgeExtensionLayer);
+ return;
+ }
+
+ startTransaction.setScale(edgeExtensionLayer, scaleX, scaleY);
+ startTransaction.reparent(edgeExtensionLayer, leash);
+ startTransaction.setLayer(edgeExtensionLayer, Integer.MIN_VALUE);
+ startTransaction.setPosition(edgeExtensionLayer, xPos, yPos);
+ startTransaction.setVisibility(edgeExtensionLayer, true);
+
+ mEdgeExtensions.get(leash).add(edgeExtensionLayer);
+ }
}
+ private float getScaleXForExtensionSurface(Rect edgeBounds, Rect extensionRect) {
+ if (edgeBounds.width() == extensionRect.width()) {
+ // Top or bottom edge extension, no need to scale the X axis of the extension surface.
+ return 1;
+ }
+ if (edgeBounds.width() == 1) {
+ // Left or right edge extension, scale the surface to be the extensionRect's width.
+ return extensionRect.width();
+ }
+
+ throw new RuntimeException("Unexpected edgeBounds and extensionRect widths");
+ }
+
+ private float getScaleYForExtensionSurface(Rect edgeBounds, Rect extensionRect) {
+ if (edgeBounds.height() == extensionRect.height()) {
+ // Left or right edge extension, no need to scale the Y axis of the extension surface.
+ return 1;
+ }
+ if (edgeBounds.height() == 1) {
+ // Top or bottom edge extension, scale the surface to be the extensionRect's height.
+ return extensionRect.height();
+ }
+
+ throw new RuntimeException("Unexpected edgeBounds and extensionRect heights");
+ }
+
+
+
private static final class RunningAnimation {
final AnimationSpec mAnimSpec;
final SurfaceControl mLeash;
@@ -513,4 +561,4 @@
return mAnimationHandler;
}
}
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 718ce28..60c280c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -28,7 +28,6 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
@@ -1720,13 +1719,6 @@
&& (topTask == null || topTask.supportsSplitScreenWindowingModeInner(tda));
}
- /** Returns {@code true} if this task is currently in split-screen. */
- boolean inSplitScreen() {
- return getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
- && getCreatedByOrganizerTask() != null
- && getCreatedByOrganizerTask().getAdjacentTaskFragment() != null;
- }
-
private boolean supportsSplitScreenWindowingModeInner(@Nullable TaskDisplayArea tda) {
return super.supportsSplitScreenWindowingMode()
&& mAtmService.mSupportsSplitScreenMultiWindow
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 1176182..ce406e4 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1163,20 +1163,21 @@
}
}
- // 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. Unless, the candidate task
- // is already positioned in the split.
- Task preferredRootInSplit = sourceTask != null && sourceTask.inSplitScreen()
- ? sourceTask.getCreatedByOrganizerTask() : null;
- if (preferredRootInSplit != null) {
- if (candidateTask != null) {
- final Task candidateRoot = candidateTask.getCreatedByOrganizerTask();
- if (candidateRoot != null && candidateRoot != preferredRootInSplit
- && preferredRootInSplit == candidateRoot.getAdjacentTaskFragment()) {
- preferredRootInSplit = candidateRoot;
+ // If a task is launching from a created-by-organizer task, it should be launched into the
+ // same created-by-organizer task as well. Unless, the candidate task is already positioned
+ // in the another adjacent task.
+ if (sourceTask != null) {
+ Task launchTarget = sourceTask.getCreatedByOrganizerTask();
+ if (launchTarget != null && launchTarget.getAdjacentTaskFragment() != null) {
+ if (candidateTask != null) {
+ final Task candidateRoot = candidateTask.getCreatedByOrganizerTask();
+ if (candidateRoot != null && candidateRoot != launchTarget
+ && launchTarget == candidateRoot.getAdjacentTaskFragment()) {
+ launchTarget = candidateRoot;
+ }
}
+ return launchTarget;
}
- return preferredRootInSplit;
}
return null;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index c7bc513..2f00bc8 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3741,8 +3741,16 @@
}
// Otherwise this is the "root" of a synced subtree, so continue on to preparation.
}
+
// This container's situation has changed so we need to restart its sync.
- mSyncState = SYNC_STATE_NONE;
+ // We cannot reset the sync without a chance of a deadlock since it will request a new
+ // buffer from the app process. This could cause issues if the app has run out of buffers
+ // since the previous buffer was already synced and is still held in a transaction.
+ // Resetting syncState violates the policies outlined in BlastSyncEngine.md so for now
+ // disable this when shell transitions is disabled.
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ mSyncState = SYNC_STATE_NONE;
+ }
prepareSync();
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 42fad6d..c0d7d13 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -23,17 +23,18 @@
import android.annotation.Nullable;
import android.content.ClipData;
import android.content.Context;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerInternal;
import android.os.Bundle;
import android.os.IBinder;
+import android.util.Pair;
import android.view.Display;
import android.view.IInputFilter;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IWindow;
import android.view.InputChannel;
-import android.view.InputWindowHandle;
import android.view.MagnificationSpec;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -433,6 +434,14 @@
public abstract IBinder getFocusedWindowToken();
/**
+ * Gets the token of the window that has input focus. It is from the focused
+ * {@link WindowState}.
+ *
+ * @return The token.
+ */
+ public abstract IBinder getFocusedWindowTokenFromWindowStates();
+
+ /**
* @return Whether the keyguard is engaged.
*/
public abstract boolean isKeyguardLocked();
@@ -451,6 +460,17 @@
public abstract void getWindowFrame(IBinder token, Rect outBounds);
/**
+ * Get the transformation matrix and MagnificationSpec given its token.
+ *
+ * @param token The token.
+ * @return The pair of the transformation matrix and magnification spec.
+ */
+ // TODO (b/231663133): Long term solution for tracking window when the
+ // FLAG_RETRIEVE_INTERACTIVE_WINDOWS is unset.
+ public abstract Pair<Matrix, MagnificationSpec>
+ getWindowTransformationMatrixAndMagnificationSpec(IBinder token);
+
+ /**
* Opens the global actions dialog.
*/
public abstract void showGlobalActions();
@@ -841,24 +861,12 @@
public abstract SurfaceControl getHandwritingSurfaceForDisplay(int displayId);
/**
- * Replaces the touchable region of the provided input surface with the crop of the window with
- * the provided token. This method will associate the inputSurface with a copy of
- * the given inputWindowHandle, where the copy is configured using
- * {@link InputWindowHandle#replaceTouchableRegionWithCrop(SurfaceControl)} with the surface
- * of the provided windowToken.
+ * Returns {@code true} if the given point is within the window bounds of the given window.
*
- * This is a no-op if windowToken is not valid or the window is not found.
- *
- * This does not change any other properties of the inputSurface.
- *
- * This method exists to avoid leaking the window's SurfaceControl outside WindowManagerService.
- *
- * @param inputSurface The surface for which the touchable region should be set.
- * @param inputWindowHandle The {@link InputWindowHandle} for the input surface.
- * @param windowToken The window whose bounds should be used as the touchable region for the
- * inputSurface.
+ * @param windowToken the window whose bounds should be used for the hit test.
+ * @param displayX the x coordinate of the test point in the display's coordinate space.
+ * @param displayY the y coordinate of the test point in the display's coordinate space.
*/
- public abstract void replaceInputSurfaceTouchableRegionWithWindowCrop(
- @NonNull SurfaceControl inputSurface, @NonNull InputWindowHandle inputWindowHandle,
- @NonNull IBinder windowToken);
+ public abstract boolean isPointInsideWindow(
+ @NonNull IBinder windowToken, int displayId, float displayX, float displayY);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 48168a0..8f1f7ec 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -172,6 +172,7 @@
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Bitmap;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -223,6 +224,7 @@
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.MergedConfiguration;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
@@ -7198,18 +7200,42 @@
private float mLatestMouseX;
private float mLatestMouseY;
- void updatePosition(float x, float y) {
+ /**
+ * The display that the pointer (mouse cursor) is currently shown on. This is updated
+ * directly by InputManagerService when the pointer display changes.
+ */
+ private int mPointerDisplayId = INVALID_DISPLAY;
+
+ /**
+ * Update the mouse cursor position as a result of a mouse movement.
+ * @return true if the position was successfully updated, false otherwise.
+ */
+ boolean updatePosition(int displayId, float x, float y) {
synchronized (this) {
mLatestEventWasMouse = true;
+
+ if (displayId != mPointerDisplayId) {
+ // The display of the position update does not match the display on which the
+ // mouse pointer is shown, so do not update the position.
+ return false;
+ }
mLatestMouseX = x;
mLatestMouseY = y;
+ return true;
+ }
+ }
+
+ void setPointerDisplayId(int displayId) {
+ synchronized (this) {
+ mPointerDisplayId = displayId;
}
}
@Override
public void onPointerEvent(MotionEvent motionEvent) {
if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) {
- updatePosition(motionEvent.getRawX(), motionEvent.getRawY());
+ updatePosition(motionEvent.getDisplayId(), motionEvent.getRawX(),
+ motionEvent.getRawY());
} else {
synchronized (this) {
mLatestEventWasMouse = false;
@@ -7219,6 +7245,7 @@
};
void updatePointerIcon(IWindow client) {
+ int pointerDisplayId;
float mouseX, mouseY;
synchronized(mMousePositionTracker) {
@@ -7227,6 +7254,7 @@
}
mouseX = mMousePositionTracker.mLatestMouseX;
mouseY = mMousePositionTracker.mLatestMouseY;
+ pointerDisplayId = mMousePositionTracker.mPointerDisplayId;
}
synchronized (mGlobalLock) {
@@ -7243,6 +7271,10 @@
if (displayContent == null) {
return;
}
+ if (pointerDisplayId != displayContent.getDisplayId()) {
+ // Do not let the pointer icon be updated by a window on a different display.
+ return;
+ }
WindowState windowUnderPointer =
displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
if (windowUnderPointer != callingWin) {
@@ -7260,7 +7292,11 @@
void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
// Mouse position tracker has not been getting updates while dragging, update it now.
- mMousePositionTracker.updatePosition(latestX, latestY);
+ if (!mMousePositionTracker.updatePosition(
+ displayContent.getDisplayId(), latestX, latestY)) {
+ // The mouse position could not be updated, so ignore this request.
+ return;
+ }
WindowState windowUnderPointer =
displayContent.getTouchableWinAtPointLocked(latestX, latestY);
@@ -7284,6 +7320,10 @@
}
}
+ void setMousePointerDisplayId(int displayId) {
+ mMousePositionTracker.setPointerDisplayId(displayId);
+ }
+
/**
* Update a tap exclude region in the window identified by the provided id. Touches down on this
* region will not:
@@ -7681,6 +7721,18 @@
}
}
+ // TODO (b/229837707): Delete this method after changing the solution.
+ @Override
+ public IBinder getFocusedWindowTokenFromWindowStates() {
+ synchronized (mGlobalLock) {
+ final WindowState windowState = getFocusedWindowLocked();
+ if (windowState != null) {
+ return windowState.mClient.asBinder();
+ }
+ return null;
+ }
+ }
+
@Override
public boolean isKeyguardLocked() {
return WindowManagerService.this.isKeyguardLocked();
@@ -7709,6 +7761,13 @@
}
@Override
+ public Pair<Matrix, MagnificationSpec> getWindowTransformationMatrixAndMagnificationSpec(
+ IBinder token) {
+ return mAccessibilityController
+ .getWindowTransformationMatrixAndMagnificationSpec(token);
+ }
+
+ @Override
public void waitForAllWindowsDrawn(Runnable callback, long timeout, int displayId) {
final WindowContainer container = displayId == INVALID_DISPLAY
? mRoot : mRoot.getDisplayContent(displayId);
@@ -8181,23 +8240,15 @@
}
@Override
- public void replaceInputSurfaceTouchableRegionWithWindowCrop(
- @NonNull SurfaceControl inputSurface,
- @NonNull InputWindowHandle inputWindowHandle,
- @NonNull IBinder windowToken) {
+ public boolean isPointInsideWindow(@NonNull IBinder windowToken, int displayId,
+ float displayX, float displayY) {
synchronized (mGlobalLock) {
final WindowState w = mWindowMap.get(windowToken);
- if (w == null) {
- return;
+ if (w == null || w.getDisplayId() != displayId) {
+ return false;
}
- // Make a copy of the InputWindowHandle to avoid leaking the window's
- // SurfaceControl.
- final InputWindowHandle localHandle = new InputWindowHandle(inputWindowHandle);
- localHandle.replaceTouchableRegionWithCrop(w.getSurfaceControl());
- final SurfaceControl.Transaction t = mTransactionFactory.get();
- t.setInputWindowInfo(inputSurface, localHandle);
- t.apply();
- t.close();
+
+ return w.getBounds().contains((int) displayX, (int) displayY);
}
}
}
@@ -8817,16 +8868,18 @@
WindowState newFocusTarget = displayContent == null
? null : displayContent.findFocusedWindow();
if (newFocusTarget == null) {
- ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus remove request for "
- + "win=%s dropped since no candidate was found",
+ t.setFocusedWindow(null, null, displayId).apply();
+ ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus win=%s"
+ + " dropped focus so setting focus to null since no candidate"
+ + " was found",
embeddedWindow);
return;
}
- t.requestFocusTransfer(newFocusTarget.mInputChannelToken, newFocusTarget.getName(),
- inputToken, embeddedWindow.toString(),
+ t.setFocusedWindow(newFocusTarget.mInputChannelToken, newFocusTarget.getName(),
displayId).apply();
+
EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
- "Transfer focus request " + newFocusTarget,
+ "Focus request " + newFocusTarget,
"reason=grantEmbeddedWindowFocus(false)");
}
ProtoLog.v(WM_DEBUG_FOCUS, "grantEmbeddedWindowFocus win=%s grantFocus=%s",
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 137a3ac..081ee2c 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -113,7 +113,8 @@
* will be filtered to only include these.
*/
static final int CONTROLLABLE_CONFIGS = ActivityInfo.CONFIG_WINDOW_CONFIGURATION
- | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_SCREEN_SIZE;
+ | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_SCREEN_SIZE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION;
static final int CONTROLLABLE_WINDOW_CONFIGS = WindowConfiguration.WINDOW_CONFIG_BOUNDS
| WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index cd19f64..3b282aa 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3639,13 +3639,11 @@
final int requested = mLastRequestedExclusionHeight[side];
final int granted = mLastGrantedExclusionHeight[side];
- final boolean inSplitScreen = getTask() != null && getTask().inSplitScreen();
-
FrameworkStatsLog.write(FrameworkStatsLog.EXCLUSION_RECT_STATE_CHANGED,
mAttrs.packageName, requested, requested - granted /* rejected */,
side + 1 /* Sides are 1-indexed in atoms.proto */,
(getConfiguration().orientation == ORIENTATION_LANDSCAPE),
- inSplitScreen, (int) duration);
+ false /* (deprecated param) inSplitscreen */, (int) duration);
}
private void initExclusionRestrictions() {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index d2e56fa..ed9b2f0 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -378,7 +378,7 @@
SurfaceControl.Builder makeSurface() {
final SurfaceControl.Builder builder = super.makeSurface();
if (mRoundedCornerOverlay) {
- builder.setParent(null);
+ builder.setParent(getDisplayContent().getSurfaceControl());
}
return builder;
}
diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
index 49a4021..93152f2 100644
--- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
+++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
@@ -66,13 +66,13 @@
// Defines the maximum amount of VMAs we can send per process_madvise syscall.
// Currently this is set to UIO_MAXIOV which is the maximum segments allowed by
// iovec implementation used by process_madvise syscall
-#define MAX_VMAS_PER_BATCH UIO_MAXIOV
+#define MAX_VMAS_PER_COMPACTION UIO_MAXIOV
// Maximum bytes that we can send per process_madvise syscall once this limit
// is reached we split the remaining VMAs into another syscall. The MAX_RW_COUNT
// limit is imposed by iovec implementation. However, if you want to use a smaller
-// limit, it has to be a page aligned value.
-#define MAX_BYTES_PER_BATCH MAX_RW_COUNT
+// limit, it has to be a page aligned value, otherwise, compaction would fail.
+#define MAX_BYTES_PER_COMPACTION MAX_RW_COUNT
// Selected a high enough number to avoid clashing with linux errno codes
#define ERROR_COMPACTION_CANCELLED -1000
@@ -83,181 +83,6 @@
// before starting next VMA batch
static std::atomic<bool> cancelRunningCompaction;
-// A VmaBatch represents a set of VMAs that can be processed
-// as VMAs are processed by client code it is expected that the
-// VMAs get consumed which means they are discarded as they are
-// processed so that the first element always is the next element
-// to be sent
-struct VmaBatch {
- struct iovec* vmas;
- // total amount of VMAs to reach the end of iovec
- int totalVmas;
- // total amount of bytes that are remaining within iovec
- uint64_t totalBytes;
-};
-
-// Advances the iterator by the specified amount of bytes.
-// This is used to remove already processed or no longer
-// needed parts of the batch.
-// Returns total bytes consumed
-int consumeBytes(VmaBatch& batch, uint64_t bytesToConsume) {
- int index = 0;
- if (CC_UNLIKELY(bytesToConsume) < 0) {
- LOG(ERROR) << "Cannot consume negative bytes for VMA batch !";
- return 0;
- }
-
- if (bytesToConsume > batch.totalBytes) {
- // Avoid consuming more bytes than available
- bytesToConsume = batch.totalBytes;
- }
-
- uint64_t bytesConsumed = 0;
- while (bytesConsumed < bytesToConsume) {
- if (CC_UNLIKELY(index >= batch.totalVmas)) {
- // reach the end of the batch
- return bytesConsumed;
- }
- if (CC_UNLIKELY(bytesConsumed + batch.vmas[index].iov_len > bytesToConsume)) {
- // this is the whole VMA that will be consumed
- break;
- }
- bytesConsumed += batch.vmas[index].iov_len;
- batch.totalBytes -= batch.vmas[index].iov_len;
- --batch.totalVmas;
- ++index;
- }
-
- // Move pointer to consume all the whole VMAs
- batch.vmas = batch.vmas + index;
-
- // Consume the rest of the bytes partially at last VMA in batch
- uint64_t bytesLeftToConsume = bytesToConsume - bytesConsumed;
- bytesConsumed += bytesLeftToConsume;
- if (batch.totalVmas > 0) {
- batch.vmas[0].iov_base = (void*)((uint64_t)batch.vmas[0].iov_base + bytesLeftToConsume);
- }
-
- return bytesConsumed;
-}
-
-// given a source of vmas this class will act as a factory
-// of VmaBatch objects and it will allow generating batches
-// until there are no more left in the source vector.
-// Note: the class does not actually modify the given
-// vmas vector, instead it iterates on it until the end.
-class VmaBatchCreator {
- const std::vector<Vma>* sourceVmas;
- // This is the destination array where batched VMAs will be stored
- // it gets encapsulated into a VmaBatch which is the object
- // meant to be used by client code.
- struct iovec* destVmas;
-
- // Parameters to keep track of the iterator on the source vmas
- int currentIndex_;
- uint64_t currentOffset_;
-
-public:
- VmaBatchCreator(const std::vector<Vma>* vmasToBatch, struct iovec* destVmasVec)
- : sourceVmas(vmasToBatch), destVmas(destVmasVec), currentIndex_(0), currentOffset_(0) {}
-
- int currentIndex() { return currentIndex_; }
- uint64_t currentOffset() { return currentOffset_; }
-
- // Generates a batch and moves the iterator on the source vmas
- // past the last VMA in the batch.
- // Returns true on success, false on failure
- bool createNextBatch(VmaBatch& batch) {
- if (currentIndex_ >= MAX_VMAS_PER_BATCH && currentIndex_ >= sourceVmas->size()) {
- return false;
- }
-
- const std::vector<Vma>& vmas = *sourceVmas;
- batch.vmas = destVmas;
- uint64_t totalBytesInBatch = 0;
- int indexInBatch = 0;
-
- // Add VMAs to the batch up until we consumed all the VMAs or
- // reached any imposed limit of VMAs per batch.
- while (indexInBatch < MAX_VMAS_PER_BATCH && currentIndex_ < vmas.size()) {
- uint64_t vmaStart = vmas[currentIndex_].start + currentOffset_;
- uint64_t vmaSize = vmas[currentIndex_].end - vmaStart;
- if (CC_UNLIKELY(vmaSize == 0)) {
- // No more bytes to batch for this VMA, move to next one
- // this only happens if a batch partially consumed bytes
- // and offset landed at exactly the end of a vma
- continue;
- }
- batch.vmas[indexInBatch].iov_base = (void*)vmaStart;
- uint64_t bytesAvailableInBatch = MAX_BYTES_PER_BATCH - totalBytesInBatch;
-
- if (vmaSize >= bytesAvailableInBatch) {
- // VMA would exceed the max available bytes in batch
- // clamp with available bytes and finish batch.
- vmaSize = bytesAvailableInBatch;
- currentOffset_ += bytesAvailableInBatch;
- }
-
- batch.vmas[indexInBatch].iov_len = vmaSize;
- totalBytesInBatch += vmaSize;
-
- ++indexInBatch;
- if (totalBytesInBatch >= MAX_BYTES_PER_BATCH) {
- // Reached max bytes quota so this marks
- // the end of the batch
- break;
- }
-
- // Fully finished current VMA, move to next one
- currentOffset_ = 0;
- ++currentIndex_;
- }
- // Vmas where fully filled and we are past the last filled index.
- batch.totalVmas = indexInBatch;
- batch.totalBytes = totalBytesInBatch;
- return true;
- }
-};
-
-// Madvise a set of VMAs given in a batch for a specific process
-// The total number of bytes successfully madvised will be set on
-// outBytesProcessed.
-// Returns 0 on success and standard linux -errno code returned by
-// process_madvise on failure
-int madviseVmasFromBatch(unique_fd& pidfd, VmaBatch& batch, int madviseType,
- uint64_t* outBytesProcessed) {
- if (batch.totalVmas == 0) {
- // No VMAs in Batch, skip.
- *outBytesProcessed = 0;
- return 0;
- }
-
- ATRACE_BEGIN(StringPrintf("Madvise %d: %d VMAs", madviseType, batch.totalVmas).c_str());
- uint64_t bytesProcessedInSend =
- process_madvise(pidfd, batch.vmas, batch.totalVmas, madviseType, 0);
- ATRACE_END();
-
- if (CC_UNLIKELY(bytesProcessedInSend == -1)) {
- bytesProcessedInSend = 0;
- if (errno != EINVAL) {
- // Forward irrecoverable errors and bail out compaction
- *outBytesProcessed = 0;
- return -errno;
- }
- }
-
- if (bytesProcessedInSend < batch.totalBytes) {
- // Did not process all the bytes requested
- // skip last page which likely failed
- bytesProcessedInSend += PAGE_SIZE;
- }
-
- bytesProcessedInSend = consumeBytes(batch, bytesProcessedInSend);
-
- *outBytesProcessed = bytesProcessedInSend;
- return 0;
-}
-
// Legacy method for compacting processes, any new code should
// use compactProcess instead.
static inline void compactProcessProcfs(int pid, const std::string& compactionType) {
@@ -271,6 +96,8 @@
// If any VMA fails compaction due to -EINVAL it will be skipped and continue.
// However, if it fails for any other reason, it will bail out and forward the error
static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseType) {
+ static struct iovec vmasToKernel[MAX_VMAS_PER_COMPACTION];
+
if (vmas.empty()) {
return 0;
}
@@ -281,16 +108,13 @@
return -errno;
}
- struct iovec destVmas[MAX_VMAS_PER_BATCH];
-
- VmaBatch batch;
- VmaBatchCreator batcher(&vmas, destVmas);
-
int64_t totalBytesProcessed = 0;
- while (batcher.createNextBatch(batch)) {
- uint64_t bytesProcessedInSend;
- do {
+ int64_t vmaOffset = 0;
+ for (int iVma = 0; iVma < vmas.size();) {
+ uint64_t bytesSentToCompact = 0;
+ int iVec = 0;
+ while (iVec < MAX_VMAS_PER_COMPACTION && iVma < vmas.size()) {
if (CC_UNLIKELY(cancelRunningCompaction.load())) {
// There could be a significant delay between when a compaction
// is requested and when it is handled during this time our
@@ -300,13 +124,50 @@
StringPrintf("Cancelled compaction for %d", pid).c_str());
return ERROR_COMPACTION_CANCELLED;
}
- int error = madviseVmasFromBatch(pidfd, batch, madviseType, &bytesProcessedInSend);
- if (error < 0) {
- // Returns standard linux errno code
- return error;
+
+ uint64_t vmaStart = vmas[iVma].start + vmaOffset;
+ uint64_t vmaSize = vmas[iVma].end - vmaStart;
+ if (vmaSize == 0) {
+ goto next_vma;
}
- totalBytesProcessed += bytesProcessedInSend;
- } while (batch.totalBytes > 0);
+ vmasToKernel[iVec].iov_base = (void*)vmaStart;
+ if (vmaSize > MAX_BYTES_PER_COMPACTION - bytesSentToCompact) {
+ // Exceeded the max bytes that could be sent, so clamp
+ // the end to avoid exceeding limit and issue compaction
+ vmaSize = MAX_BYTES_PER_COMPACTION - bytesSentToCompact;
+ }
+
+ vmasToKernel[iVec].iov_len = vmaSize;
+ bytesSentToCompact += vmaSize;
+ ++iVec;
+ if (bytesSentToCompact >= MAX_BYTES_PER_COMPACTION) {
+ // Ran out of bytes within iovec, dispatch compaction.
+ vmaOffset += vmaSize;
+ break;
+ }
+
+ next_vma:
+ // Finished current VMA, and have more bytes remaining
+ vmaOffset = 0;
+ ++iVma;
+ }
+
+ ATRACE_BEGIN(StringPrintf("Compact %d VMAs", iVec).c_str());
+ auto bytesProcessed = process_madvise(pidfd, vmasToKernel, iVec, madviseType, 0);
+ ATRACE_END();
+
+ if (CC_UNLIKELY(bytesProcessed == -1)) {
+ if (errno == EINVAL) {
+ // This error is somewhat common due to an unevictable VMA if this is
+ // the case silently skip the bad VMA and continue compacting the rest.
+ continue;
+ } else {
+ // Forward irrecoverable errors and bail out compaction
+ return -errno;
+ }
+ }
+
+ totalBytesProcessed += bytesProcessed;
}
return totalBytesProcessed;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 3c5ebe7..32adac7 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -107,6 +107,7 @@
jmethodID interceptKeyBeforeDispatching;
jmethodID dispatchUnhandledKey;
jmethodID checkInjectEventsPermission;
+ jmethodID onPointerDisplayIdChanged;
jmethodID onPointerDownOutsideFocus;
jmethodID getVirtualKeyQuietTimeMillis;
jmethodID getExcludedDeviceNames;
@@ -120,7 +121,6 @@
jmethodID getLongPressTimeout;
jmethodID getPointerLayer;
jmethodID getPointerIcon;
- jmethodID getPointerDisplayId;
jmethodID getKeyboardLayoutOverlay;
jmethodID getDeviceAlias;
jmethodID getTouchCalibrationForInputDevice;
@@ -277,6 +277,7 @@
void setFocusedDisplay(int32_t displayId);
void setInputDispatchMode(bool enabled, bool frozen);
void setSystemUiLightsOut(bool lightsOut);
+ void setPointerDisplayId(int32_t displayId);
void setPointerSpeed(int32_t speed);
void setPointerAcceleration(float acceleration);
void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
@@ -288,7 +289,6 @@
void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled);
void setCustomPointerIcon(const SpriteIcon& icon);
void setMotionClassifierEnabled(bool enabled);
- void notifyPointerDisplayIdChanged();
/* --- InputReaderPolicyInterface implementation --- */
@@ -346,6 +346,7 @@
std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId);
virtual int32_t getDefaultPointerIconId();
virtual int32_t getCustomPointerIconId();
+ virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos);
private:
sp<InputManagerInterface> mInputManager;
@@ -394,7 +395,6 @@
void updateInactivityTimeoutLocked();
void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
void ensureSpriteControllerLocked();
- int32_t getPointerDisplayId();
sp<SurfaceControl> getParentSurfaceForPointers(int displayId);
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
@@ -498,13 +498,9 @@
}
}
- // Get the preferred pointer controller displayId.
- int32_t pointerDisplayId = getPointerDisplayId();
-
{ // acquire lock
AutoMutex _l(mLock);
mLocked.viewports = viewports;
- mLocked.pointerDisplayId = pointerDisplayId;
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
controller->onDisplayViewportsUpdated(mLocked.viewports);
@@ -666,15 +662,12 @@
return controller;
}
-int32_t NativeInputManager::getPointerDisplayId() {
+void NativeInputManager::onPointerDisplayIdChanged(int32_t pointerDisplayId, float xPos,
+ float yPos) {
JNIEnv* env = jniEnv();
- jint pointerDisplayId = env->CallIntMethod(mServiceObj,
- gServiceClassInfo.getPointerDisplayId);
- if (checkAndClearExceptionFromCallback(env, "getPointerDisplayId")) {
- pointerDisplayId = ADISPLAY_ID_DEFAULT;
- }
-
- return pointerDisplayId;
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDisplayIdChanged, pointerDisplayId,
+ xPos, yPos);
+ checkAndClearExceptionFromCallback(env, "onPointerDisplayIdChanged");
}
sp<SurfaceControl> NativeInputManager::getParentSurfaceForPointers(int displayId) {
@@ -1032,6 +1025,22 @@
: InactivityTimeout::NORMAL);
}
+void NativeInputManager::setPointerDisplayId(int32_t displayId) {
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (mLocked.pointerDisplayId == displayId) {
+ return;
+ }
+
+ ALOGI("Setting pointer display id to %d.", displayId);
+ mLocked.pointerDisplayId = displayId;
+ } // release lock
+
+ mInputManager->getReader().requestRefreshConfiguration(
+ InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+}
+
void NativeInputManager::setPointerSpeed(int32_t speed) {
{ // acquire lock
AutoMutex _l(mLock);
@@ -1494,18 +1503,6 @@
mInputManager->getClassifier().setMotionClassifierEnabled(enabled);
}
-void NativeInputManager::notifyPointerDisplayIdChanged() {
- int32_t pointerDisplayId = getPointerDisplayId();
-
- { // acquire lock
- AutoMutex _l(mLock);
- mLocked.pointerDisplayId = pointerDisplayId;
- } // release lock
-
- mInputManager->getReader().requestRefreshConfiguration(
- InputReaderConfiguration::CHANGE_DISPLAY_INFO);
-}
-
// ----------------------------------------------------------------------------
static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
@@ -2199,11 +2196,6 @@
InputReaderConfiguration::CHANGE_DISPLAY_INFO);
}
-static void nativeNotifyPointerDisplayIdChanged(JNIEnv* env, jobject nativeImplObj) {
- NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
- im->notifyPointerDisplayIdChanged();
-}
-
static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jobject nativeImplObj,
jint displayId, jboolean isEligible) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
@@ -2321,6 +2313,11 @@
im->getInputManager()->getDispatcher().cancelCurrentTouch();
}
+static void nativeSetPointerDisplayId(JNIEnv* env, jobject nativeImplObj, jint displayId) {
+ NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+ im->setPointerDisplayId(displayId);
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod gInputManagerMethods[] = {
@@ -2393,7 +2390,6 @@
{"canDispatchToDisplay", "(II)Z", (void*)nativeCanDispatchToDisplay},
{"notifyPortAssociationsChanged", "()V", (void*)nativeNotifyPortAssociationsChanged},
{"changeUniqueIdAssociation", "()V", (void*)nativeChangeUniqueIdAssociation},
- {"notifyPointerDisplayIdChanged", "()V", (void*)nativeNotifyPointerDisplayIdChanged},
{"setDisplayEligibilityForPointerCapture", "(IZ)V",
(void*)nativeSetDisplayEligibilityForPointerCapture},
{"setMotionClassifierEnabled", "(Z)V", (void*)nativeSetMotionClassifierEnabled},
@@ -2403,6 +2399,7 @@
{"disableSensor", "(II)V", (void*)nativeDisableSensor},
{"flushSensor", "(II)Z", (void*)nativeFlushSensor},
{"cancelCurrentTouch", "()V", (void*)nativeCancelCurrentTouch},
+ {"setPointerDisplayId", "(I)V", (void*)nativeSetPointerDisplayId},
};
#define FIND_CLASS(var, className) \
@@ -2498,6 +2495,9 @@
GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
"checkInjectEventsPermission", "(II)Z");
+ GET_METHOD_ID(gServiceClassInfo.onPointerDisplayIdChanged, clazz, "onPointerDisplayIdChanged",
+ "(IFF)V");
+
GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
"onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
@@ -2537,9 +2537,6 @@
GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
"getPointerIcon", "(I)Landroid/view/PointerIcon;");
- GET_METHOD_ID(gServiceClassInfo.getPointerDisplayId, clazz,
- "getPointerDisplayId", "()I");
-
GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
"getKeyboardLayoutOverlay",
"(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0a426eb..7f466f3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -279,7 +279,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -679,6 +678,7 @@
final Context mContext;
final Injector mInjector;
+ final PolicyPathProvider mPathProvider;
final IPackageManager mIPackageManager;
final IPermissionManager mIPermissionManager;
final UserManager mUserManager;
@@ -890,7 +890,7 @@
}
@GuardedBy("getLockObject()")
- final SparseArray<DevicePolicyData> mUserData = new SparseArray<>();
+ final SparseArray<DevicePolicyData> mUserData;
@GuardedBy("getLockObject()")
@@ -1365,7 +1365,7 @@
public final Context mContext;
- private @Nullable DevicePolicySafetyChecker mSafetyChecker;
+ @Nullable private DevicePolicySafetyChecker mSafetyChecker;
Injector(Context context) {
mContext = context;
@@ -1384,12 +1384,6 @@
return mContext.getResources();
}
- Owners newOwners() {
- return new Owners(getUserManager(), getUserManagerInternal(),
- getPackageManagerInternal(), getActivityTaskManagerInternal(),
- getActivityManagerInternal());
- }
-
UserManager getUserManager() {
return UserManager.get(mContext);
}
@@ -1595,10 +1589,6 @@
return UserHandle.getUserId(binderGetCallingUid());
}
- File environmentGetUserSystemDirectory(int userId) {
- return Environment.getUserSystemDirectory(userId);
- }
-
void powerManagerGoToSleep(long time, int reason, int flags) {
mContext.getSystemService(PowerManager.class).goToSleep(time, reason, flags);
}
@@ -1641,10 +1631,6 @@
return UserManager.isHeadlessSystemUserMode();
}
- String getDevicePolicyFilePathForSystemUser() {
- return "/data/system/";
- }
-
@SuppressWarnings("AndroidFrameworkPendingIntentMutability")
PendingIntent pendingIntentGetActivityAsUser(Context context, int requestCode,
@NonNull Intent intent, int flags, Bundle options, UserHandle user) {
@@ -1777,14 +1763,16 @@
* Instantiates the service.
*/
public DevicePolicyManagerService(Context context) {
- this(new Injector(context.createAttributionContext(ATTRIBUTION_TAG)));
+ this(new Injector(
+ context.createAttributionContext(ATTRIBUTION_TAG)), new PolicyPathProvider() {});
}
@VisibleForTesting
- DevicePolicyManagerService(Injector injector) {
+ DevicePolicyManagerService(Injector injector, PolicyPathProvider pathProvider) {
DevicePolicyManager.disableLocalCaches();
mInjector = injector;
+ mPathProvider = pathProvider;
mContext = Objects.requireNonNull(injector.mContext);
mHandler = new Handler(Objects.requireNonNull(injector.getMyLooper()));
@@ -1792,8 +1780,6 @@
mConstantsObserver.register();
mConstants = loadConstants();
- mOwners = Objects.requireNonNull(injector.newOwners());
-
mUserManager = Objects.requireNonNull(injector.getUserManager());
mUserManagerInternal = Objects.requireNonNull(injector.getUserManagerInternal());
mUsageStatsManagerInternal = Objects.requireNonNull(
@@ -1831,12 +1817,23 @@
// "Lite" interface is available even when the device doesn't have the feature
LocalServices.addService(DevicePolicyManagerLiteInternal.class, mLocalService);
+
+ // Policy version upgrade must not depend on either mOwners or mUserData, so they are
+ // initialized only after performing the upgrade.
+ if (mHasFeature) {
+ performPolicyVersionUpgrade();
+ }
+ mUserData = new SparseArray<>();
+ mOwners = makeOwners(injector, pathProvider);
+
if (!mHasFeature) {
// Skip the rest of the initialization
mSetupContentObserver = null;
return;
}
+ loadOwners();
+
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
@@ -1872,16 +1869,19 @@
new RestrictionsListener(mContext, mUserManagerInternal, this));
mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
- loadOwners();
-
- performPolicyVersionUpgrade();
-
mDeviceManagementResourcesProvider.load();
// The binder caches are not enabled until the first invalidation.
invalidateBinderCaches();
}
+ private Owners makeOwners(Injector injector, PolicyPathProvider pathProvider) {
+ return new Owners(injector.getUserManager(), injector.getUserManagerInternal(),
+ injector.getPackageManagerInternal(),
+ injector.getActivityTaskManagerInternal(),
+ injector.getActivityManagerInternal(), pathProvider);
+ }
+
/**
* Invalidate the binder API caches. The invalidation itself does not require any
* locking, but this specific call should be protected by getLockObject() to ensure
@@ -1975,8 +1975,8 @@
mUserData.remove(userHandle);
}
- File policyFile = new File(mInjector.environmentGetUserSystemDirectory(userHandle),
- DEVICE_POLICIES_XML);
+ File policyFile =
+ new File(mPathProvider.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML);
policyFile.delete();
Slogf.i(LOG_TAG, "Removed device policy file " + policyFile.getAbsolutePath());
}
@@ -2879,8 +2879,8 @@
private File getPolicyFileDirectory(@UserIdInt int userId) {
return userId == UserHandle.USER_SYSTEM
- ? new File(mInjector.getDevicePolicyFilePathForSystemUser())
- : mInjector.environmentGetUserSystemDirectory(userId);
+ ? mPathProvider.getDataSystemDirectory()
+ : mPathProvider.getUserSystemDirectory(userId);
}
private JournaledFile makeJournaledFile(@UserIdInt int userId, String fileName) {
@@ -3087,14 +3087,9 @@
updateUsbDataSignal();
}
+ // TODO(b/230841522) Make it static.
private class DpmsUpgradeDataProvider implements PolicyUpgraderDataProvider {
@Override
- public boolean isDeviceOwner(int userId, ComponentName who) {
- return mOwners.isDeviceOwnerUserId(userId)
- && mOwners.getDeviceOwnerComponent().equals(who);
- }
-
- @Override
public boolean storageManagerIsFileBasedEncryptionEnabled() {
return mInjector.storageManagerIsFileBasedEncryptionEnabled();
}
@@ -3110,14 +3105,9 @@
}
@Override
- public ComponentName getOwnerComponent(int userId) {
- return DevicePolicyManagerService.this.getOwnerComponent(userId);
- }
-
- @Override
public Function<ComponentName, DeviceAdminInfo> getAdminInfoSupplier(int userId) {
- return component -> findAdmin(component, userId, /* throwForMissingPermission= */
- false);
+ return component ->
+ findAdmin(component, userId, /* throwForMissingPermission= */ false);
}
@Override
@@ -3128,7 +3118,8 @@
}
private void performPolicyVersionUpgrade() {
- PolicyVersionUpgrader upgrader = new PolicyVersionUpgrader(new DpmsUpgradeDataProvider());
+ PolicyVersionUpgrader upgrader = new PolicyVersionUpgrader(
+ new DpmsUpgradeDataProvider(), mPathProvider);
upgrader.upgradePolicy(DPMS_VERSION);
}
@@ -8522,6 +8513,13 @@
}
}
+ private boolean isDeviceOwnerUserId(int userId) {
+ synchronized (getLockObject()) {
+ return mOwners.getDeviceOwnerComponent() != null
+ && mOwners.getDeviceOwnerUserId() == userId;
+ }
+ }
+
private boolean isDeviceOwnerPackage(String packageName, int userId) {
synchronized (getLockObject()) {
return mOwners.hasDeviceOwner()
@@ -12126,10 +12124,11 @@
return;
}
final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(isProfileOwner(caller)
+ Preconditions.checkCallAuthorization((isProfileOwner(caller)
+ && isManagedProfile(caller.getUserId()))
|| isDefaultDeviceOwner(caller),
- "Caller is not profile owner or device owner;"
- + " only profile owner or device owner may control the preferential"
+ "Caller is not managed profile owner or device owner;"
+ + " only managed profile owner or device owner may control the preferential"
+ " network service");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getDeviceOrProfileOwnerAdminLocked(
@@ -12156,11 +12155,12 @@
}
final CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(isProfileOwner(caller)
+ Preconditions.checkCallAuthorization((isProfileOwner(caller)
+ && isManagedProfile(caller.getUserId()))
|| isDefaultDeviceOwner(caller),
- "Caller is not profile owner or device owner;"
- + " only profile owner or device owner may retrieve the preferential"
- + " network service configurations");
+ "Caller is not managed profile owner or device owner;"
+ + " only managed profile owner or device owner may retrieve the "
+ + "preferential network service configurations");
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getDeviceOrProfileOwnerAdminLocked(
caller.getUserId());
@@ -16280,7 +16280,7 @@
synchronized (getLockObject()) {
final int callingUserId = caller.getUserId();
final File bundleFile = new File(
- mInjector.environmentGetUserSystemDirectory(callingUserId),
+ mPathProvider.getUserSystemDirectory(callingUserId),
TRANSFER_OWNERSHIP_PARAMETERS_XML);
if (!bundleFile.exists()) {
return null;
@@ -16474,7 +16474,7 @@
@VisibleForTesting
void saveTransferOwnershipBundleLocked(PersistableBundle bundle, int userId) {
final File parametersFile = new File(
- mInjector.environmentGetUserSystemDirectory(userId),
+ mPathProvider.getUserSystemDirectory(userId),
TRANSFER_OWNERSHIP_PARAMETERS_XML);
final AtomicFile atomicFile = new AtomicFile(parametersFile);
FileOutputStream stream = null;
@@ -16496,7 +16496,7 @@
}
void deleteTransferOwnershipBundleLocked(int userId) {
- final File parametersFile = new File(mInjector.environmentGetUserSystemDirectory(userId),
+ final File parametersFile = new File(mPathProvider.getUserSystemDirectory(userId),
TRANSFER_OWNERSHIP_PARAMETERS_XML);
parametersFile.delete();
}
@@ -18275,7 +18275,7 @@
private void updateNetworkPreferenceForUser(int userId,
List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs) {
- if (!isManagedProfile(userId)) {
+ if (!isManagedProfile(userId) && !isDeviceOwnerUserId(userId)) {
return;
}
List<ProfileNetworkPreference> preferences = new ArrayList<>();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 859183c..d1c6b34 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -27,43 +27,30 @@
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.UserInfo;
import android.os.Binder;
-import android.os.Environment;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.AtomicFile;
import android.util.IndentingPrintWriter;
-import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
-import android.util.TypedXmlPullParser;
-import android.util.TypedXmlSerializer;
-import android.util.Xml;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
+import com.android.server.devicepolicy.OwnersData.OwnerInfo;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParserException;
-
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -79,125 +66,51 @@
private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
- // XML storing device owner info, system update policy and pending OTA update information.
- private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
-
- private static final String PROFILE_OWNER_XML = "profile_owner.xml";
-
- private static final String TAG_ROOT = "root";
-
- private static final String TAG_DEVICE_OWNER = "device-owner";
- private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
- private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record";
- private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
- private static final String TAG_PROFILE_OWNER = "profile-owner";
- // Holds "context" for device-owner, this must not be show up before device-owner.
- private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
- private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type";
- private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES =
- "device-owner-protected-packages";
-
- private static final String ATTR_NAME = "name";
- private static final String ATTR_PACKAGE = "package";
- private static final String ATTR_COMPONENT_NAME = "component";
- private static final String ATTR_SIZE = "size";
- private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
- private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
- private static final String ATTR_USERID = "userId";
- private static final String ATTR_FREEZE_RECORD_START = "start";
- private static final String ATTR_FREEZE_RECORD_END = "end";
- // Legacy attribute, its presence would mean the profile owner associated with it is
- // managing a profile on an organization-owned device.
- private static final String ATTR_CAN_ACCESS_DEVICE_IDS = "canAccessDeviceIds";
- // New attribute for profile owner of organization-owned device.
- private static final String ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE =
- "isPoOrganizationOwnedDevice";
- private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
-
private final UserManager mUserManager;
private final UserManagerInternal mUserManagerInternal;
private final PackageManagerInternal mPackageManagerInternal;
private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
private final ActivityManagerInternal mActivityManagerInternal;
+ @GuardedBy("mData")
+ private final OwnersData mData;
+
private boolean mSystemReady;
- // Internal state for the device owner package.
- private OwnerInfo mDeviceOwner;
-
- // Device owner type for a managed device.
- private final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>();
-
- private final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
-
- private int mDeviceOwnerUserId = UserHandle.USER_NULL;
-
- // Internal state for the profile owner packages.
- private final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
-
- // Local system update policy controllable by device owner.
- private SystemUpdatePolicy mSystemUpdatePolicy;
- private LocalDate mSystemUpdateFreezeStart;
- private LocalDate mSystemUpdateFreezeEnd;
-
- // Pending OTA info if there is one.
- @Nullable
- private SystemUpdateInfo mSystemUpdateInfo;
-
- private final Object mLock = new Object();
- private final Injector mInjector;
-
- public Owners(UserManager userManager,
- UserManagerInternal userManagerInternal,
- PackageManagerInternal packageManagerInternal,
- ActivityTaskManagerInternal activityTaskManagerInternal,
- ActivityManagerInternal activitykManagerInternal) {
- this(userManager, userManagerInternal, packageManagerInternal,
- activityTaskManagerInternal, activitykManagerInternal, new Injector());
- }
-
@VisibleForTesting
Owners(UserManager userManager,
UserManagerInternal userManagerInternal,
PackageManagerInternal packageManagerInternal,
ActivityTaskManagerInternal activityTaskManagerInternal,
ActivityManagerInternal activityManagerInternal,
- Injector injector) {
+ PolicyPathProvider pathProvider) {
mUserManager = userManager;
mUserManagerInternal = userManagerInternal;
mPackageManagerInternal = packageManagerInternal;
mActivityTaskManagerInternal = activityTaskManagerInternal;
mActivityManagerInternal = activityManagerInternal;
- mInjector = injector;
+ mData = new OwnersData(pathProvider);
}
/**
* Load configuration from the disk.
*/
void load() {
- synchronized (mLock) {
- final List<UserInfo> users = mUserManager.getAliveUsers();
-
- new DeviceOwnerReadWriter().readFromFileLocked();
-
- for (UserInfo ui : users) {
- new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
- }
+ synchronized (mData) {
+ int[] usersIds =
+ mUserManager.getAliveUsers().stream().mapToInt(u -> u.id).toArray();
+ mData.load(usersIds);
mUserManagerInternal.setDeviceManaged(hasDeviceOwner());
- for (UserInfo ui : users) {
- mUserManagerInternal.setUserManaged(ui.id, hasProfileOwner(ui.id));
- }
- if (hasDeviceOwner() && hasProfileOwner(getDeviceOwnerUserId())) {
- Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
- getDeviceOwnerUserId()));
+ for (int userId : usersIds) {
+ mUserManagerInternal.setUserManaged(userId, hasProfileOwner(userId));
}
notifyChangeLocked();
pushToActivityTaskManagerLocked();
for (ArrayMap.Entry<String, List<String>> entry :
- mDeviceOwnerProtectedPackages.entrySet()) {
+ mData.mDeviceOwnerProtectedPackages.entrySet()) {
mPackageManagerInternal.setDeviceOwnerProtectedPackages(
entry.getKey(), entry.getValue());
}
@@ -206,6 +119,7 @@
// Notify interested parties that things have changed. This does not notify the
// ActivityTaskManager.
+ @GuardedBy("mData")
private void notifyChangeLocked() {
pushToDevicePolicyManager();
pushToPackageManagerLocked();
@@ -219,28 +133,31 @@
DevicePolicyManagerService.invalidateBinderCaches();
}
+ @GuardedBy("mData")
private void pushToPackageManagerLocked() {
final SparseArray<String> po = new SparseArray<>();
- for (int i = mProfileOwners.size() - 1; i >= 0; i--) {
- po.put(mProfileOwners.keyAt(i), mProfileOwners.valueAt(i).packageName);
+ for (int i = mData.mProfileOwners.size() - 1; i >= 0; i--) {
+ po.put(mData.mProfileOwners.keyAt(i), mData.mProfileOwners.valueAt(i).packageName);
}
+ final String doPackage = mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null;
mPackageManagerInternal.setDeviceAndProfileOwnerPackages(
- mDeviceOwnerUserId, (mDeviceOwner != null ? mDeviceOwner.packageName : null),
- po);
+ mData.mDeviceOwnerUserId, doPackage, po);
}
+ @GuardedBy("mData")
private void pushToActivityTaskManagerLocked() {
mActivityTaskManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
}
+ @GuardedBy("mData")
private void pushToActivityManagerLocked() {
mActivityManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
final ArraySet<Integer> profileOwners = new ArraySet<>();
- for (int poi = mProfileOwners.size() - 1; poi >= 0; poi--) {
- final int userId = mProfileOwners.keyAt(poi);
+ for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) {
+ final int userId = mData.mProfileOwners.keyAt(poi);
final int profileOwnerUid = mPackageManagerInternal.getPackageUid(
- mProfileOwners.valueAt(poi).packageName,
+ mData.mProfileOwners.valueAt(poi).packageName,
PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
userId);
if (profileOwnerUid >= 0) {
@@ -250,60 +167,61 @@
mActivityManagerInternal.setProfileOwnerUid(profileOwners);
}
+ @GuardedBy("mData")
int getDeviceOwnerUidLocked() {
- if (mDeviceOwner != null) {
- return mPackageManagerInternal.getPackageUid(mDeviceOwner.packageName,
+ if (mData.mDeviceOwner != null) {
+ return mPackageManagerInternal.getPackageUid(mData.mDeviceOwner.packageName,
PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
- mDeviceOwnerUserId);
+ mData.mDeviceOwnerUserId);
} else {
return Process.INVALID_UID;
}
}
String getDeviceOwnerPackageName() {
- synchronized (mLock) {
- return mDeviceOwner != null ? mDeviceOwner.packageName : null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null;
}
}
int getDeviceOwnerUserId() {
- synchronized (mLock) {
- return mDeviceOwnerUserId;
+ synchronized (mData) {
+ return mData.mDeviceOwnerUserId;
}
}
@Nullable
Pair<Integer, ComponentName> getDeviceOwnerUserIdAndComponent() {
- synchronized (mLock) {
- if (mDeviceOwner == null) {
+ synchronized (mData) {
+ if (mData.mDeviceOwner == null) {
return null;
} else {
- return Pair.create(mDeviceOwnerUserId, mDeviceOwner.admin);
+ return Pair.create(mData.mDeviceOwnerUserId, mData.mDeviceOwner.admin);
}
}
}
String getDeviceOwnerName() {
- synchronized (mLock) {
- return mDeviceOwner != null ? mDeviceOwner.name : null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null ? mData.mDeviceOwner.name : null;
}
}
ComponentName getDeviceOwnerComponent() {
- synchronized (mLock) {
- return mDeviceOwner != null ? mDeviceOwner.admin : null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null ? mData.mDeviceOwner.admin : null;
}
}
String getDeviceOwnerRemoteBugreportUri() {
- synchronized (mLock) {
- return mDeviceOwner != null ? mDeviceOwner.remoteBugreportUri : null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportUri : null;
}
}
String getDeviceOwnerRemoteBugreportHash() {
- synchronized (mLock) {
- return mDeviceOwner != null ? mDeviceOwner.remoteBugreportHash : null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportHash : null;
}
}
@@ -312,13 +230,13 @@
Slog.e(TAG, "Invalid user id for device owner user: " + userId);
return;
}
- synchronized (mLock) {
+ synchronized (mData) {
// A device owner is allowed to access device identifiers. Even though this flag
// is not currently checked for device owner, it is set to true here so that it is
// semantically compatible with the meaning of this flag.
- mDeviceOwner = new OwnerInfo(ownerName, admin, /* remoteBugreportUri =*/ null,
+ mData.mDeviceOwner = new OwnerInfo(ownerName, admin, /* remoteBugreportUri =*/ null,
/* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true);
- mDeviceOwnerUserId = userId;
+ mData.mDeviceOwnerUserId = userId;
mUserManagerInternal.setDeviceManaged(true);
notifyChangeLocked();
@@ -327,16 +245,16 @@
}
void clearDeviceOwner() {
- synchronized (mLock) {
- mDeviceOwnerTypes.remove(mDeviceOwner.packageName);
+ synchronized (mData) {
+ mData.mDeviceOwnerTypes.remove(mData.mDeviceOwner.packageName);
List<String> protectedPackages =
- mDeviceOwnerProtectedPackages.remove(mDeviceOwner.packageName);
+ mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName);
if (protectedPackages != null) {
mPackageManagerInternal.setDeviceOwnerProtectedPackages(
- mDeviceOwner.packageName, new ArrayList<>());
+ mData.mDeviceOwner.packageName, new ArrayList<>());
}
- mDeviceOwner = null;
- mDeviceOwnerUserId = UserHandle.USER_NULL;
+ mData.mDeviceOwner = null;
+ mData.mDeviceOwnerUserId = UserHandle.USER_NULL;
mUserManagerInternal.setDeviceManaged(false);
notifyChangeLocked();
@@ -345,9 +263,9 @@
}
void setProfileOwner(ComponentName admin, String ownerName, int userId) {
- synchronized (mLock) {
+ synchronized (mData) {
// For a newly set PO, there's no need for migration.
- mProfileOwners.put(userId, new OwnerInfo(ownerName, admin,
+ mData.mProfileOwners.put(userId, new OwnerInfo(ownerName, admin,
/* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null,
/* isOrganizationOwnedDevice =*/ false));
mUserManagerInternal.setUserManaged(userId, true);
@@ -356,43 +274,48 @@
}
void removeProfileOwner(int userId) {
- synchronized (mLock) {
- mProfileOwners.remove(userId);
+ synchronized (mData) {
+ mData.mProfileOwners.remove(userId);
mUserManagerInternal.setUserManaged(userId, false);
notifyChangeLocked();
}
}
void transferProfileOwner(ComponentName target, int userId) {
- synchronized (mLock) {
- final OwnerInfo ownerInfo = mProfileOwners.get(userId);
+ synchronized (mData) {
+ final OwnerInfo ownerInfo = mData.mProfileOwners.get(userId);
final OwnerInfo newOwnerInfo = new OwnerInfo(target.getPackageName(), target,
ownerInfo.remoteBugreportUri, ownerInfo.remoteBugreportHash,
ownerInfo.isOrganizationOwnedDevice);
- mProfileOwners.put(userId, newOwnerInfo);
+ mData.mProfileOwners.put(userId, newOwnerInfo);
notifyChangeLocked();
}
}
void transferDeviceOwnership(ComponentName target) {
- synchronized (mLock) {
- Integer previousDeviceOwnerType = mDeviceOwnerTypes.remove(mDeviceOwner.packageName);
+ synchronized (mData) {
+ Integer previousDeviceOwnerType = mData.mDeviceOwnerTypes.remove(
+ mData.mDeviceOwner.packageName);
List<String> previousProtectedPackages =
- mDeviceOwnerProtectedPackages.remove(mDeviceOwner.packageName);
+ mData.mDeviceOwnerProtectedPackages.remove(mData.mDeviceOwner.packageName);
if (previousProtectedPackages != null) {
mPackageManagerInternal.setDeviceOwnerProtectedPackages(
- mDeviceOwner.packageName, new ArrayList<>());
+ mData.mDeviceOwner.packageName, new ArrayList<>());
}
// We don't set a name because it's not used anyway.
// See DevicePolicyManagerService#getDeviceOwnerName
- mDeviceOwner = new OwnerInfo(null, target, mDeviceOwner.remoteBugreportUri,
- mDeviceOwner.remoteBugreportHash, mDeviceOwner.isOrganizationOwnedDevice);
+ mData.mDeviceOwner = new OwnerInfo(null, target,
+ mData.mDeviceOwner.remoteBugreportUri,
+ mData.mDeviceOwner.remoteBugreportHash,
+ mData.mDeviceOwner.isOrganizationOwnedDevice);
+
if (previousDeviceOwnerType != null) {
- mDeviceOwnerTypes.put(mDeviceOwner.packageName, previousDeviceOwnerType);
+ mData.mDeviceOwnerTypes.put(
+ mData.mDeviceOwner.packageName, previousDeviceOwnerType);
}
if (previousProtectedPackages != null) {
- mDeviceOwnerProtectedPackages.put(
- mDeviceOwner.packageName, previousProtectedPackages);
+ mData.mDeviceOwnerProtectedPackages.put(
+ mData.mDeviceOwner.packageName, previousProtectedPackages);
}
notifyChangeLocked();
pushToActivityTaskManagerLocked();
@@ -400,22 +323,22 @@
}
ComponentName getProfileOwnerComponent(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
+ synchronized (mData) {
+ OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
return profileOwner != null ? profileOwner.admin : null;
}
}
String getProfileOwnerName(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
+ synchronized (mData) {
+ OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
return profileOwner != null ? profileOwner.name : null;
}
}
String getProfileOwnerPackage(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
+ synchronized (mData) {
+ OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
return profileOwner != null ? profileOwner.packageName : null;
}
}
@@ -425,27 +348,28 @@
* organization-owned device, as indicated by the provisioning flow.
*/
boolean isProfileOwnerOfOrganizationOwnedDevice(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
+ synchronized (mData) {
+ OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
return profileOwner != null ? profileOwner.isOrganizationOwnedDevice : false;
}
}
Set<Integer> getProfileOwnerKeys() {
- synchronized (mLock) {
- return mProfileOwners.keySet();
+ synchronized (mData) {
+ return mData.mProfileOwners.keySet();
}
}
List<OwnerShellData> listAllOwners() {
List<OwnerShellData> owners = new ArrayList<>();
- synchronized (mLock) {
- if (mDeviceOwner != null) {
- owners.add(OwnerShellData.forDeviceOwner(mDeviceOwnerUserId, mDeviceOwner.admin));
+ synchronized (mData) {
+ if (mData.mDeviceOwner != null) {
+ owners.add(OwnerShellData.forDeviceOwner(mData.mDeviceOwnerUserId,
+ mData.mDeviceOwner.admin));
}
- for (int i = 0; i < mProfileOwners.size(); i++) {
- int userId = mProfileOwners.keyAt(i);
- OwnerInfo info = mProfileOwners.valueAt(i);
+ for (int i = 0; i < mData.mProfileOwners.size(); i++) {
+ int userId = mData.mProfileOwners.keyAt(i);
+ OwnerInfo info = mData.mProfileOwners.valueAt(i);
owners.add(OwnerShellData.forUserProfileOwner(userId, info.admin));
}
}
@@ -454,44 +378,34 @@
SystemUpdatePolicy getSystemUpdatePolicy() {
- synchronized (mLock) {
- return mSystemUpdatePolicy;
+ synchronized (mData) {
+ return mData.mSystemUpdatePolicy;
}
}
void setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy) {
- synchronized (mLock) {
- mSystemUpdatePolicy = systemUpdatePolicy;
+ synchronized (mData) {
+ mData.mSystemUpdatePolicy = systemUpdatePolicy;
}
}
void clearSystemUpdatePolicy() {
- synchronized (mLock) {
- mSystemUpdatePolicy = null;
+ synchronized (mData) {
+ mData.mSystemUpdatePolicy = null;
}
}
Pair<LocalDate, LocalDate> getSystemUpdateFreezePeriodRecord() {
- synchronized (mLock) {
- return new Pair<>(mSystemUpdateFreezeStart, mSystemUpdateFreezeEnd);
+ synchronized (mData) {
+ return new Pair<>(mData.mSystemUpdateFreezeStart,
+ mData.mSystemUpdateFreezeEnd);
}
}
String getSystemUpdateFreezePeriodRecordAsString() {
- StringBuilder freezePeriodRecord = new StringBuilder();
- freezePeriodRecord.append("start: ");
- if (mSystemUpdateFreezeStart != null) {
- freezePeriodRecord.append(mSystemUpdateFreezeStart.toString());
- } else {
- freezePeriodRecord.append("null");
+ synchronized (mData) {
+ return mData.getSystemUpdateFreezePeriodRecordAsString();
}
- freezePeriodRecord.append("; end: ");
- if (mSystemUpdateFreezeEnd != null) {
- freezePeriodRecord.append(mSystemUpdateFreezeEnd.toString());
- } else {
- freezePeriodRecord.append("null");
- }
- return freezePeriodRecord.toString();
}
/**
@@ -499,13 +413,13 @@
*/
boolean setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end) {
boolean changed = false;
- synchronized (mLock) {
- if (!Objects.equals(mSystemUpdateFreezeStart, start)) {
- mSystemUpdateFreezeStart = start;
+ synchronized (mData) {
+ if (!Objects.equals(mData.mSystemUpdateFreezeStart, start)) {
+ mData.mSystemUpdateFreezeStart = start;
changed = true;
}
- if (!Objects.equals(mSystemUpdateFreezeEnd, end)) {
- mSystemUpdateFreezeEnd = end;
+ if (!Objects.equals(mData.mSystemUpdateFreezeEnd, end)) {
+ mData.mSystemUpdateFreezeEnd = end;
changed = true;
}
}
@@ -513,19 +427,19 @@
}
boolean hasDeviceOwner() {
- synchronized (mLock) {
- return mDeviceOwner != null;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null;
}
}
boolean isDeviceOwnerUserId(int userId) {
- synchronized (mLock) {
- return mDeviceOwner != null && mDeviceOwnerUserId == userId;
+ synchronized (mData) {
+ return mData.mDeviceOwner != null && mData.mDeviceOwnerUserId == userId;
}
}
boolean hasProfileOwner(int userId) {
- synchronized (mLock) {
+ synchronized (mData) {
return getProfileOwnerComponent(userId) != null;
}
}
@@ -533,10 +447,10 @@
/** Sets the remote bugreport uri and hash, and also writes to the file. */
void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri,
String remoteBugreportHash) {
- synchronized (mLock) {
- if (mDeviceOwner != null) {
- mDeviceOwner.remoteBugreportUri = remoteBugreportUri;
- mDeviceOwner.remoteBugreportHash = remoteBugreportHash;
+ synchronized (mData) {
+ if (mData.mDeviceOwner != null) {
+ mData.mDeviceOwner.remoteBugreportUri = remoteBugreportUri;
+ mData.mDeviceOwner.remoteBugreportHash = remoteBugreportHash;
}
writeDeviceOwner();
}
@@ -544,8 +458,8 @@
/** Set whether the profile owner manages an organization-owned device, then write to file. */
void setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
+ synchronized (mData) {
+ OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
if (profileOwner != null) {
profileOwner.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
} else {
@@ -558,7 +472,7 @@
void setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType,
boolean isAdminTestOnly) {
- synchronized (mLock) {
+ synchronized (mData) {
if (!hasDeviceOwner()) {
Slog.e(TAG, "Attempting to set a device owner type when there is no device owner");
return;
@@ -568,71 +482,67 @@
return;
}
- mDeviceOwnerTypes.put(packageName, deviceOwnerType);
+ mData.mDeviceOwnerTypes.put(packageName, deviceOwnerType);
writeDeviceOwner();
}
}
@DeviceOwnerType
int getDeviceOwnerType(String packageName) {
- synchronized (mLock) {
+ synchronized (mData) {
if (isDeviceOwnerTypeSetForDeviceOwner(packageName)) {
- return mDeviceOwnerTypes.get(packageName);
+ return mData.mDeviceOwnerTypes.get(packageName);
}
return DEVICE_OWNER_TYPE_DEFAULT;
}
}
boolean isDeviceOwnerTypeSetForDeviceOwner(String packageName) {
- synchronized (mLock) {
- return !mDeviceOwnerTypes.isEmpty() && mDeviceOwnerTypes.containsKey(packageName);
+ synchronized (mData) {
+ return !mData.mDeviceOwnerTypes.isEmpty()
+ && mData.mDeviceOwnerTypes.containsKey(packageName);
}
}
void setDeviceOwnerProtectedPackages(String packageName, List<String> protectedPackages) {
- synchronized (mLock) {
+ synchronized (mData) {
if (!hasDeviceOwner()) {
Slog.e(TAG,
"Attempting to set device owner protected packages when there is no "
+ "device owner");
return;
- } else if (!mDeviceOwner.packageName.equals(packageName)) {
+ } else if (!mData.mDeviceOwner.packageName.equals(packageName)) {
Slog.e(TAG, "Attempting to set device owner protected packages when the provided "
+ "package name " + packageName
+ " does not match the device owner package name");
return;
}
- mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
+ mData.mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
mPackageManagerInternal.setDeviceOwnerProtectedPackages(packageName, protectedPackages);
writeDeviceOwner();
}
}
List<String> getDeviceOwnerProtectedPackages(String packageName) {
- synchronized (mLock) {
- return mDeviceOwnerProtectedPackages.containsKey(packageName)
- ? mDeviceOwnerProtectedPackages.get(packageName) : Collections.emptyList();
+ synchronized (mData) {
+ return mData.mDeviceOwnerProtectedPackages.containsKey(packageName)
+ ? mData.mDeviceOwnerProtectedPackages.get(packageName)
+ : Collections.emptyList();
}
}
void writeDeviceOwner() {
- synchronized (mLock) {
- if (DEBUG) {
- Log.d(TAG, "Writing to device owner file");
- }
+ synchronized (mData) {
pushToDevicePolicyManager();
- new DeviceOwnerReadWriter().writeToFileLocked();
+ mData.writeDeviceOwner();
}
}
void writeProfileOwner(int userId) {
- synchronized (mLock) {
- if (DEBUG) {
- Log.d(TAG, "Writing to profile owner file for user " + userId);
- }
+ synchronized (mData) {
pushToDevicePolicyManager();
- new ProfileOwnerReadWriter(userId).writeToFileLocked();
+ mData.writeProfileOwner(userId);
}
}
@@ -643,25 +553,26 @@
* @return Whether the saved system update information has changed.
*/
boolean saveSystemUpdateInfo(@Nullable SystemUpdateInfo newInfo) {
- synchronized (mLock) {
+ synchronized (mData) {
// Check if we already have the same update information.
- if (Objects.equals(newInfo, mSystemUpdateInfo)) {
+ if (Objects.equals(newInfo, mData.mSystemUpdateInfo)) {
return false;
}
- mSystemUpdateInfo = newInfo;
- new DeviceOwnerReadWriter().writeToFileLocked();
+ mData.mSystemUpdateInfo = newInfo;
+ mData.writeDeviceOwner();
return true;
}
}
@Nullable
public SystemUpdateInfo getSystemUpdateInfo() {
- synchronized (mLock) {
- return mSystemUpdateInfo;
+ synchronized (mData) {
+ return mData.mSystemUpdateInfo;
}
}
+ @GuardedBy("mData")
void pushToAppOpsLocked() {
if (!mSystemReady) {
return;
@@ -669,20 +580,20 @@
final long ident = Binder.clearCallingIdentity();
try {
final SparseIntArray owners = new SparseIntArray();
- if (mDeviceOwner != null) {
+ if (mData.mDeviceOwner != null) {
final int uid = getDeviceOwnerUidLocked();
if (uid >= 0) {
- owners.put(mDeviceOwnerUserId, uid);
+ owners.put(mData.mDeviceOwnerUserId, uid);
}
}
- if (mProfileOwners != null) {
- for (int poi = mProfileOwners.size() - 1; poi >= 0; poi--) {
+ if (mData.mProfileOwners != null) {
+ for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) {
final int uid = mPackageManagerInternal.getPackageUid(
- mProfileOwners.valueAt(poi).packageName,
+ mData.mProfileOwners.valueAt(poi).packageName,
PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
- mProfileOwners.keyAt(poi));
+ mData.mProfileOwners.keyAt(poi));
if (uid >= 0) {
- owners.put(mProfileOwners.keyAt(poi), uid);
+ owners.put(mData.mProfileOwners.keyAt(poi), uid);
}
}
}
@@ -696,435 +607,26 @@
}
public void systemReady() {
- synchronized (mLock) {
+ synchronized (mData) {
mSystemReady = true;
pushToActivityManagerLocked();
pushToAppOpsLocked();
}
}
- private abstract static class FileReadWriter {
- private final File mFile;
-
- protected FileReadWriter(File file) {
- mFile = file;
- }
-
- abstract boolean shouldWrite();
-
- void writeToFileLocked() {
- if (!shouldWrite()) {
- if (DEBUG) {
- Log.d(TAG, "No need to write to " + mFile);
- }
- // No contents, remove the file.
- if (mFile.exists()) {
- if (DEBUG) {
- Log.d(TAG, "Deleting existing " + mFile);
- }
- if (!mFile.delete()) {
- Slog.e(TAG, "Failed to remove " + mFile.getPath());
- }
- }
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "Writing to " + mFile);
- }
-
- final AtomicFile f = new AtomicFile(mFile);
- FileOutputStream outputStream = null;
- try {
- outputStream = f.startWrite();
- final TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
-
- // Root tag
- out.startDocument(null, true);
- out.startTag(null, TAG_ROOT);
-
- // Actual content
- writeInner(out);
-
- // Close root
- out.endTag(null, TAG_ROOT);
- out.endDocument();
- out.flush();
-
- // Commit the content.
- f.finishWrite(outputStream);
- outputStream = null;
-
- } catch (IOException e) {
- Slog.e(TAG, "Exception when writing", e);
- if (outputStream != null) {
- f.failWrite(outputStream);
- }
- }
- }
-
- void readFromFileLocked() {
- if (!mFile.exists()) {
- if (DEBUG) {
- Log.d(TAG, "" + mFile + " doesn't exist");
- }
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "Reading from " + mFile);
- }
- final AtomicFile f = new AtomicFile(mFile);
- InputStream input = null;
- try {
- input = f.openRead();
- final TypedXmlPullParser parser = Xml.resolvePullParser(input);
-
- int type;
- int depth = 0;
- while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
- switch (type) {
- case TypedXmlPullParser.START_TAG:
- depth++;
- break;
- case TypedXmlPullParser.END_TAG:
- depth--;
- // fallthrough
- default:
- continue;
- }
- // Check the root tag
- final String tag = parser.getName();
- if (depth == 1) {
- if (!TAG_ROOT.equals(tag)) {
- Slog.e(TAG, "Invalid root tag: " + tag);
- return;
- }
- continue;
- }
- // readInner() will only see START_TAG at depth >= 2.
- if (!readInner(parser, depth, tag)) {
- return; // Error
- }
- }
- } catch (XmlPullParserException | IOException e) {
- Slog.e(TAG, "Error parsing owners information file", e);
- } finally {
- IoUtils.closeQuietly(input);
- }
- }
-
- abstract void writeInner(TypedXmlSerializer out) throws IOException;
-
- abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag);
- }
-
- private class DeviceOwnerReadWriter extends FileReadWriter {
-
- protected DeviceOwnerReadWriter() {
- super(getDeviceOwnerFile());
- }
-
- @Override
- boolean shouldWrite() {
- return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
- || (mSystemUpdateInfo != null);
- }
-
- @Override
- void writeInner(TypedXmlSerializer out) throws IOException {
- if (mDeviceOwner != null) {
- mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
- out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
- out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
- out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
-
- }
-
- if (!mDeviceOwnerTypes.isEmpty()) {
- for (ArrayMap.Entry<String, Integer> entry : mDeviceOwnerTypes.entrySet()) {
- out.startTag(null, TAG_DEVICE_OWNER_TYPE);
- out.attribute(null, ATTR_PACKAGE, entry.getKey());
- out.attributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE, entry.getValue());
- out.endTag(null, TAG_DEVICE_OWNER_TYPE);
- }
- }
-
- if (!mDeviceOwnerProtectedPackages.isEmpty()) {
- for (ArrayMap.Entry<String, List<String>> entry :
- mDeviceOwnerProtectedPackages.entrySet()) {
- List<String> protectedPackages = entry.getValue();
-
- out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
- out.attribute(null, ATTR_PACKAGE, entry.getKey());
- out.attributeInt(null, ATTR_SIZE, protectedPackages.size());
- for (int i = 0, size = protectedPackages.size(); i < size; i++) {
- out.attribute(null, ATTR_NAME + i, protectedPackages.get(i));
- }
- out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
- }
- }
-
- if (mSystemUpdatePolicy != null) {
- out.startTag(null, TAG_SYSTEM_UPDATE_POLICY);
- mSystemUpdatePolicy.saveToXml(out);
- out.endTag(null, TAG_SYSTEM_UPDATE_POLICY);
- }
-
- if (mSystemUpdateInfo != null) {
- mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO);
- }
-
- if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
- out.startTag(null, TAG_FREEZE_PERIOD_RECORD);
- if (mSystemUpdateFreezeStart != null) {
- out.attribute(null, ATTR_FREEZE_RECORD_START,
- mSystemUpdateFreezeStart.toString());
- }
- if (mSystemUpdateFreezeEnd != null) {
- out.attribute(null, ATTR_FREEZE_RECORD_END, mSystemUpdateFreezeEnd.toString());
- }
- out.endTag(null, TAG_FREEZE_PERIOD_RECORD);
- }
- }
-
- @Override
- boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
- if (depth > 2) {
- return true; // Ignore
- }
- switch (tag) {
- case TAG_DEVICE_OWNER:
- mDeviceOwner = OwnerInfo.readFromXml(parser);
- mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
- break;
- case TAG_DEVICE_OWNER_CONTEXT: {
- mDeviceOwnerUserId = parser.getAttributeInt(null, ATTR_USERID,
- mDeviceOwnerUserId);
- break;
- }
- case TAG_SYSTEM_UPDATE_POLICY:
- mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
- break;
- case TAG_PENDING_OTA_INFO:
- mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser);
- break;
- case TAG_FREEZE_PERIOD_RECORD:
- String startDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_START);
- String endDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_END);
- if (startDate != null && endDate != null) {
- mSystemUpdateFreezeStart = LocalDate.parse(startDate);
- mSystemUpdateFreezeEnd = LocalDate.parse(endDate);
- if (mSystemUpdateFreezeStart.isAfter(mSystemUpdateFreezeEnd)) {
- Slog.e(TAG, "Invalid system update freeze record loaded");
- mSystemUpdateFreezeStart = null;
- mSystemUpdateFreezeEnd = null;
- }
- }
- break;
- case TAG_DEVICE_OWNER_TYPE:
- String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- int deviceOwnerType = parser.getAttributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE,
- DEVICE_OWNER_TYPE_DEFAULT);
- mDeviceOwnerTypes.put(packageName, deviceOwnerType);
- break;
- case TAG_DEVICE_OWNER_PROTECTED_PACKAGES:
- packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0);
- List<String> protectedPackages = new ArrayList<>();
- for (int i = 0; i < protectedPackagesSize; i++) {
- protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i));
- }
- mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
- break;
- default:
- Slog.e(TAG, "Unexpected tag: " + tag);
- return false;
- }
- return true;
- }
- }
-
- private class ProfileOwnerReadWriter extends FileReadWriter {
- private final int mUserId;
-
- ProfileOwnerReadWriter(int userId) {
- super(getProfileOwnerFile(userId));
- mUserId = userId;
- }
-
- @Override
- boolean shouldWrite() {
- return mProfileOwners.get(mUserId) != null;
- }
-
- @Override
- void writeInner(TypedXmlSerializer out) throws IOException {
- final OwnerInfo profileOwner = mProfileOwners.get(mUserId);
- if (profileOwner != null) {
- profileOwner.writeToXml(out, TAG_PROFILE_OWNER);
- }
- }
-
- @Override
- boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
- if (depth > 2) {
- return true; // Ignore
- }
- switch (tag) {
- case TAG_PROFILE_OWNER:
- mProfileOwners.put(mUserId, OwnerInfo.readFromXml(parser));
- break;
- default:
- Slog.e(TAG, "Unexpected tag: " + tag);
- return false;
-
- }
- return true;
- }
- }
-
- static class OwnerInfo {
- public final String name;
- public final String packageName;
- public final ComponentName admin;
- public String remoteBugreportUri;
- public String remoteBugreportHash;
- public boolean isOrganizationOwnedDevice;
-
- OwnerInfo(String name, ComponentName admin,
- String remoteBugreportUri, String remoteBugreportHash,
- boolean isOrganizationOwnedDevice) {
- this.name = name;
- this.admin = admin;
- this.packageName = admin.getPackageName();
- this.remoteBugreportUri = remoteBugreportUri;
- this.remoteBugreportHash = remoteBugreportHash;
- this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
- }
-
- public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
- out.startTag(null, tag);
- if (name != null) {
- out.attribute(null, ATTR_NAME, name);
- }
- if (admin != null) {
- out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
- }
- if (remoteBugreportUri != null) {
- out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
- }
- if (remoteBugreportHash != null) {
- out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
- }
- if (isOrganizationOwnedDevice) {
- out.attributeBoolean(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE,
- isOrganizationOwnedDevice);
- }
- out.endTag(null, tag);
- }
-
- public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
- final String name = parser.getAttributeValue(null, ATTR_NAME);
- final String componentName =
- parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
- final String remoteBugreportUri = parser.getAttributeValue(null,
- ATTR_REMOTE_BUGREPORT_URI);
- final String remoteBugreportHash = parser.getAttributeValue(null,
- ATTR_REMOTE_BUGREPORT_HASH);
- final String canAccessDeviceIdsStr =
- parser.getAttributeValue(null, ATTR_CAN_ACCESS_DEVICE_IDS);
- final boolean canAccessDeviceIds =
- ("true".equals(canAccessDeviceIdsStr));
- final String isOrgOwnedDeviceStr =
- parser.getAttributeValue(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE);
- final boolean isOrgOwnedDevice =
- ("true".equals(isOrgOwnedDeviceStr)) | canAccessDeviceIds;
-
- if (componentName == null) {
- Slog.e(TAG, "Owner component not found");
- return null;
- }
- final ComponentName admin = ComponentName.unflattenFromString(componentName);
- if (admin == null) {
- Slog.e(TAG, "Owner component not parsable: " + componentName);
- return null;
- }
-
- return new OwnerInfo(
- name, admin, remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
- }
-
- public void dump(IndentingPrintWriter pw) {
- pw.println("admin=" + admin);
- pw.println("name=" + name);
- pw.println("package=" + packageName);
- pw.println("isOrganizationOwnedDevice=" + isOrganizationOwnedDevice);
- }
- }
-
public void dump(IndentingPrintWriter pw) {
- boolean needBlank = false;
- if (mDeviceOwner != null) {
- pw.println("Device Owner: ");
- pw.increaseIndent();
- mDeviceOwner.dump(pw);
- pw.println("User ID: " + mDeviceOwnerUserId);
- pw.decreaseIndent();
- needBlank = true;
- }
- if (mSystemUpdatePolicy != null) {
- if (needBlank) {
- pw.println();
- }
- pw.println("System Update Policy: " + mSystemUpdatePolicy);
- needBlank = true;
- }
- if (mProfileOwners != null) {
- for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
- if (needBlank) {
- pw.println();
- }
- pw.println("Profile Owner (User " + entry.getKey() + "): ");
- pw.increaseIndent();
- entry.getValue().dump(pw);
- pw.decreaseIndent();
- needBlank = true;
- }
- }
- if (mSystemUpdateInfo != null) {
- if (needBlank) {
- pw.println();
- }
- pw.println("Pending System Update: " + mSystemUpdateInfo);
- needBlank = true;
- }
- if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
- if (needBlank) {
- pw.println();
- }
- pw.println("System update freeze record: "
- + getSystemUpdateFreezePeriodRecordAsString());
- needBlank = true;
+ synchronized (mData) {
+ mData.dump(pw);
}
}
@VisibleForTesting
File getDeviceOwnerFile() {
- return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML);
+ return mData.getDeviceOwnerFile();
}
@VisibleForTesting
File getProfileOwnerFile(int userId) {
- return new File(mInjector.environmentGetUserSystemDirectory(userId), PROFILE_OWNER_XML);
- }
-
- @VisibleForTesting
- public static class Injector {
- File environmentGetDataSystemDirectory() {
- return Environment.getDataSystemDirectory();
- }
-
- File environmentGetUserSystemDirectory(int userId) {
- return Environment.getUserSystemDirectory(userId);
- }
+ return mData.getProfileOwnerFile(userId);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
new file mode 100644
index 0000000..4fe4f0d
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -0,0 +1,579 @@
+/*
+ * 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.devicepolicy;
+
+import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
+
+import android.annotation.Nullable;
+import android.app.admin.SystemUpdateInfo;
+import android.app.admin.SystemUpdatePolicy;
+import android.content.ComponentName;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+class OwnersData {
+ private static final String TAG = "DevicePolicyManagerService";
+
+ private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
+
+ // XML storing device owner info, system update policy and pending OTA update information.
+ private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
+ private static final String PROFILE_OWNER_XML = "profile_owner.xml";
+
+ private static final String TAG_ROOT = "root";
+ private static final String TAG_DEVICE_OWNER = "device-owner";
+ private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
+ private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record";
+ private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
+ private static final String TAG_PROFILE_OWNER = "profile-owner";
+ // Holds "context" for device-owner, this must not be show up before device-owner.
+ private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
+ private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type";
+ private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES =
+ "device-owner-protected-packages";
+
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_PACKAGE = "package";
+ private static final String ATTR_COMPONENT_NAME = "component";
+ private static final String ATTR_SIZE = "size";
+ private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
+ private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
+ private static final String ATTR_USERID = "userId";
+ private static final String ATTR_FREEZE_RECORD_START = "start";
+ private static final String ATTR_FREEZE_RECORD_END = "end";
+ // Legacy attribute, its presence would mean the profile owner associated with it is
+ // managing a profile on an organization-owned device.
+ private static final String ATTR_CAN_ACCESS_DEVICE_IDS = "canAccessDeviceIds";
+ // New attribute for profile owner of organization-owned device.
+ private static final String ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE =
+ "isPoOrganizationOwnedDevice";
+ private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
+
+ // Internal state for the device owner package.
+ OwnerInfo mDeviceOwner;
+ int mDeviceOwnerUserId = UserHandle.USER_NULL;
+
+ // Device owner type for a managed device.
+ final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>();
+
+ final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
+
+
+ // Internal state for the profile owner packages.
+ final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
+
+ // Local system update policy controllable by device owner.
+ SystemUpdatePolicy mSystemUpdatePolicy;
+ LocalDate mSystemUpdateFreezeStart;
+ LocalDate mSystemUpdateFreezeEnd;
+
+ // Pending OTA info if there is one.
+ @Nullable
+ SystemUpdateInfo mSystemUpdateInfo;
+ private final PolicyPathProvider mPathProvider;
+
+ OwnersData(PolicyPathProvider pathProvider) {
+ mPathProvider = pathProvider;
+ }
+
+ void load(int[] allUsers) {
+ new DeviceOwnerReadWriter().readFromFileLocked();
+
+ for (int userId : allUsers) {
+ new ProfileOwnerReadWriter(userId).readFromFileLocked();
+ }
+
+ OwnerInfo profileOwner = mProfileOwners.get(mDeviceOwnerUserId);
+ ComponentName admin = profileOwner != null ? profileOwner.admin : null;
+ if (mDeviceOwner != null && admin != null) {
+ Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
+ mDeviceOwnerUserId));
+ }
+ }
+
+ /**
+ * @return true upon success, false otherwise.
+ */
+ boolean writeDeviceOwner() {
+ if (DEBUG) {
+ Log.d(TAG, "Writing to device owner file");
+ }
+ return new DeviceOwnerReadWriter().writeToFileLocked();
+ }
+
+ /**
+ * @return true upon success, false otherwise.
+ */
+ boolean writeProfileOwner(int userId) {
+ if (DEBUG) {
+ Log.d(TAG, "Writing to profile owner file for user " + userId);
+ }
+ return new ProfileOwnerReadWriter(userId).writeToFileLocked();
+ }
+
+ void dump(IndentingPrintWriter pw) {
+ boolean needBlank = false;
+ if (mDeviceOwner != null) {
+ pw.println("Device Owner: ");
+ pw.increaseIndent();
+ mDeviceOwner.dump(pw);
+ pw.println("User ID: " + mDeviceOwnerUserId);
+ pw.decreaseIndent();
+ needBlank = true;
+ }
+ if (mSystemUpdatePolicy != null) {
+ if (needBlank) {
+ pw.println();
+ }
+ pw.println("System Update Policy: " + mSystemUpdatePolicy);
+ needBlank = true;
+ }
+ if (mProfileOwners != null) {
+ for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
+ if (needBlank) {
+ pw.println();
+ }
+ pw.println("Profile Owner (User " + entry.getKey() + "): ");
+ pw.increaseIndent();
+ entry.getValue().dump(pw);
+ pw.decreaseIndent();
+ needBlank = true;
+ }
+ }
+ if (mSystemUpdateInfo != null) {
+ if (needBlank) {
+ pw.println();
+ }
+ pw.println("Pending System Update: " + mSystemUpdateInfo);
+ needBlank = true;
+ }
+ if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
+ if (needBlank) {
+ pw.println();
+ }
+ pw.println("System update freeze record: "
+ + getSystemUpdateFreezePeriodRecordAsString());
+ needBlank = true;
+ }
+ }
+
+ String getSystemUpdateFreezePeriodRecordAsString() {
+ StringBuilder freezePeriodRecord = new StringBuilder();
+ freezePeriodRecord.append("start: ");
+ if (mSystemUpdateFreezeStart != null) {
+ freezePeriodRecord.append(mSystemUpdateFreezeStart.toString());
+ } else {
+ freezePeriodRecord.append("null");
+ }
+ freezePeriodRecord.append("; end: ");
+ if (mSystemUpdateFreezeEnd != null) {
+ freezePeriodRecord.append(mSystemUpdateFreezeEnd.toString());
+ } else {
+ freezePeriodRecord.append("null");
+ }
+ return freezePeriodRecord.toString();
+ }
+
+ @VisibleForTesting
+ File getDeviceOwnerFile() {
+ return new File(mPathProvider.getDataSystemDirectory(), DEVICE_OWNER_XML);
+ }
+
+ @VisibleForTesting
+ File getProfileOwnerFile(int userId) {
+ return new File(mPathProvider.getUserSystemDirectory(userId), PROFILE_OWNER_XML);
+ }
+
+ private abstract static class FileReadWriter {
+ private final File mFile;
+
+ protected FileReadWriter(File file) {
+ mFile = file;
+ }
+
+ abstract boolean shouldWrite();
+
+ boolean writeToFileLocked() {
+ if (!shouldWrite()) {
+ if (DEBUG) {
+ Log.d(TAG, "No need to write to " + mFile);
+ }
+ // No contents, remove the file.
+ if (mFile.exists()) {
+ if (DEBUG) {
+ Log.d(TAG, "Deleting existing " + mFile);
+ }
+ if (!mFile.delete()) {
+ Slog.e(TAG, "Failed to remove " + mFile.getPath());
+ }
+ }
+ return true;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Writing to " + mFile);
+ }
+
+ final AtomicFile f = new AtomicFile(mFile);
+ FileOutputStream outputStream = null;
+ try {
+ outputStream = f.startWrite();
+ final TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
+
+ // Root tag
+ out.startDocument(null, true);
+ out.startTag(null, TAG_ROOT);
+
+ // Actual content
+ writeInner(out);
+
+ // Close root
+ out.endTag(null, TAG_ROOT);
+ out.endDocument();
+ out.flush();
+
+ // Commit the content.
+ f.finishWrite(outputStream);
+ outputStream = null;
+
+ } catch (IOException e) {
+ Slog.e(TAG, "Exception when writing", e);
+ if (outputStream != null) {
+ f.failWrite(outputStream);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ void readFromFileLocked() {
+ if (!mFile.exists()) {
+ if (DEBUG) {
+ Log.d(TAG, "" + mFile + " doesn't exist");
+ }
+ return;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "Reading from " + mFile);
+ }
+ final AtomicFile f = new AtomicFile(mFile);
+ InputStream input = null;
+ try {
+ input = f.openRead();
+ final TypedXmlPullParser parser = Xml.resolvePullParser(input);
+
+ int type;
+ int depth = 0;
+ while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
+ switch (type) {
+ case TypedXmlPullParser.START_TAG:
+ depth++;
+ break;
+ case TypedXmlPullParser.END_TAG:
+ depth--;
+ // fallthrough
+ default:
+ continue;
+ }
+ // Check the root tag
+ final String tag = parser.getName();
+ if (depth == 1) {
+ if (!TAG_ROOT.equals(tag)) {
+ Slog.e(TAG, "Invalid root tag: " + tag);
+ return;
+ }
+ continue;
+ }
+ // readInner() will only see START_TAG at depth >= 2.
+ if (!readInner(parser, depth, tag)) {
+ return; // Error
+ }
+ }
+ } catch (XmlPullParserException | IOException e) {
+ Slog.e(TAG, "Error parsing owners information file", e);
+ } finally {
+ IoUtils.closeQuietly(input);
+ }
+ }
+
+ abstract void writeInner(TypedXmlSerializer out) throws IOException;
+
+ abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag);
+ }
+
+ private class DeviceOwnerReadWriter extends FileReadWriter {
+
+ protected DeviceOwnerReadWriter() {
+ super(getDeviceOwnerFile());
+ }
+
+ @Override
+ boolean shouldWrite() {
+ return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
+ || (mSystemUpdateInfo != null);
+ }
+
+ @Override
+ void writeInner(TypedXmlSerializer out) throws IOException {
+ if (mDeviceOwner != null) {
+ mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
+ out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
+ out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
+ out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
+
+ }
+
+ if (!mDeviceOwnerTypes.isEmpty()) {
+ for (ArrayMap.Entry<String, Integer> entry : mDeviceOwnerTypes.entrySet()) {
+ out.startTag(null, TAG_DEVICE_OWNER_TYPE);
+ out.attribute(null, ATTR_PACKAGE, entry.getKey());
+ out.attributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE, entry.getValue());
+ out.endTag(null, TAG_DEVICE_OWNER_TYPE);
+ }
+ }
+
+ if (!mDeviceOwnerProtectedPackages.isEmpty()) {
+ for (ArrayMap.Entry<String, List<String>> entry :
+ mDeviceOwnerProtectedPackages.entrySet()) {
+ List<String> protectedPackages = entry.getValue();
+
+ out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
+ out.attribute(null, ATTR_PACKAGE, entry.getKey());
+ out.attributeInt(null, ATTR_SIZE, protectedPackages.size());
+ for (int i = 0, size = protectedPackages.size(); i < size; i++) {
+ out.attribute(null, ATTR_NAME + i, protectedPackages.get(i));
+ }
+ out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
+ }
+ }
+
+ if (mSystemUpdatePolicy != null) {
+ out.startTag(null, TAG_SYSTEM_UPDATE_POLICY);
+ mSystemUpdatePolicy.saveToXml(out);
+ out.endTag(null, TAG_SYSTEM_UPDATE_POLICY);
+ }
+
+ if (mSystemUpdateInfo != null) {
+ mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO);
+ }
+
+ if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
+ out.startTag(null, TAG_FREEZE_PERIOD_RECORD);
+ if (mSystemUpdateFreezeStart != null) {
+ out.attribute(
+ null, ATTR_FREEZE_RECORD_START, mSystemUpdateFreezeStart.toString());
+ }
+ if (mSystemUpdateFreezeEnd != null) {
+ out.attribute(null, ATTR_FREEZE_RECORD_END, mSystemUpdateFreezeEnd.toString());
+ }
+ out.endTag(null, TAG_FREEZE_PERIOD_RECORD);
+ }
+ }
+
+ @Override
+ boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
+ if (depth > 2) {
+ return true; // Ignore
+ }
+ switch (tag) {
+ case TAG_DEVICE_OWNER:
+ mDeviceOwner = OwnerInfo.readFromXml(parser);
+ mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
+ break;
+ case TAG_DEVICE_OWNER_CONTEXT: {
+ mDeviceOwnerUserId =
+ parser.getAttributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
+ break;
+ }
+ case TAG_SYSTEM_UPDATE_POLICY:
+ mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
+ break;
+ case TAG_PENDING_OTA_INFO:
+ mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser);
+ break;
+ case TAG_FREEZE_PERIOD_RECORD:
+ String startDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_START);
+ String endDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_END);
+ if (startDate != null && endDate != null) {
+ mSystemUpdateFreezeStart = LocalDate.parse(startDate);
+ mSystemUpdateFreezeEnd = LocalDate.parse(endDate);
+ if (mSystemUpdateFreezeStart.isAfter(mSystemUpdateFreezeEnd)) {
+ Slog.e(TAG, "Invalid system update freeze record loaded");
+ mSystemUpdateFreezeStart = null;
+ mSystemUpdateFreezeEnd = null;
+ }
+ }
+ break;
+ case TAG_DEVICE_OWNER_TYPE:
+ String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+ int deviceOwnerType = parser.getAttributeInt(
+ null, ATTR_DEVICE_OWNER_TYPE_VALUE, DEVICE_OWNER_TYPE_DEFAULT);
+ mDeviceOwnerTypes.put(packageName, deviceOwnerType);
+ break;
+ case TAG_DEVICE_OWNER_PROTECTED_PACKAGES:
+ packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+ int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0);
+ List<String> protectedPackages = new ArrayList<>();
+ for (int i = 0; i < protectedPackagesSize; i++) {
+ protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i));
+ }
+ mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
+ break;
+ default:
+ Slog.e(TAG, "Unexpected tag: " + tag);
+ return false;
+
+ }
+ return true;
+ }
+ }
+
+ private class ProfileOwnerReadWriter extends FileReadWriter {
+ private final int mUserId;
+
+ ProfileOwnerReadWriter(int userId) {
+ super(getProfileOwnerFile(userId));
+ mUserId = userId;
+ }
+
+ @Override
+ boolean shouldWrite() {
+ return mProfileOwners.get(mUserId) != null;
+ }
+
+ @Override
+ void writeInner(TypedXmlSerializer out) throws IOException {
+ final OwnerInfo profileOwner = mProfileOwners.get(mUserId);
+ if (profileOwner != null) {
+ profileOwner.writeToXml(out, TAG_PROFILE_OWNER);
+ }
+ }
+
+ @Override
+ boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
+ if (depth > 2) {
+ return true; // Ignore
+ }
+ switch (tag) {
+ case TAG_PROFILE_OWNER:
+ mProfileOwners.put(mUserId, OwnerInfo.readFromXml(parser));
+ break;
+ default:
+ Slog.e(TAG, "Unexpected tag: " + tag);
+ return false;
+
+ }
+ return true;
+ }
+ }
+
+ static class OwnerInfo {
+ public final String name;
+ public final String packageName;
+ public final ComponentName admin;
+ public String remoteBugreportUri;
+ public String remoteBugreportHash;
+ public boolean isOrganizationOwnedDevice;
+
+ OwnerInfo(String name, ComponentName admin, String remoteBugreportUri,
+ String remoteBugreportHash, boolean isOrganizationOwnedDevice) {
+ this.name = name;
+ this.admin = admin;
+ this.packageName = admin.getPackageName();
+ this.remoteBugreportUri = remoteBugreportUri;
+ this.remoteBugreportHash = remoteBugreportHash;
+ this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
+ }
+
+ public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
+ out.startTag(null, tag);
+ if (name != null) {
+ out.attribute(null, ATTR_NAME, name);
+ }
+ if (admin != null) {
+ out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
+ }
+ if (remoteBugreportUri != null) {
+ out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
+ }
+ if (remoteBugreportHash != null) {
+ out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
+ }
+ if (isOrganizationOwnedDevice) {
+ out.attributeBoolean(
+ null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE, isOrganizationOwnedDevice);
+ }
+ out.endTag(null, tag);
+ }
+
+ public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
+ final String name = parser.getAttributeValue(null, ATTR_NAME);
+ final String componentName = parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
+ final String remoteBugreportUri =
+ parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_URI);
+ final String remoteBugreportHash =
+ parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_HASH);
+ final String canAccessDeviceIdsStr =
+ parser.getAttributeValue(null, ATTR_CAN_ACCESS_DEVICE_IDS);
+ final boolean canAccessDeviceIds = "true".equals(canAccessDeviceIdsStr);
+ final String isOrgOwnedDeviceStr =
+ parser.getAttributeValue(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE);
+ final boolean isOrgOwnedDevice =
+ "true".equals(isOrgOwnedDeviceStr) | canAccessDeviceIds;
+
+ if (componentName == null) {
+ Slog.e(TAG, "Owner component not found");
+ return null;
+ }
+ final ComponentName admin = ComponentName.unflattenFromString(componentName);
+ if (admin == null) {
+ Slog.e(TAG, "Owner component not parsable: " + componentName);
+ return null;
+ }
+
+ return new OwnerInfo(
+ name, admin, remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
+ }
+
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("admin=" + admin);
+ pw.println("name=" + name);
+ pw.println("package=" + packageName);
+ pw.println("isOrganizationOwnedDevice=" + isOrganizationOwnedDevice);
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyPathProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyPathProvider.java
new file mode 100644
index 0000000..96cc0e5
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyPathProvider.java
@@ -0,0 +1,42 @@
+/*
+ * 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.devicepolicy;
+
+import android.os.Environment;
+
+import java.io.File;
+
+/**
+ * Interface providing directories for various DPMS files.
+ */
+public interface PolicyPathProvider {
+ /**
+ * Returns policy data directory for system user, typically /data/system
+ * Used for SYSTEM_USER policies, device owner file and policy version file.
+ */
+ default File getDataSystemDirectory() {
+ return Environment.getDataSystemDirectory();
+ }
+
+ /**
+ * Returns policy data directory for a given user, typically /data/system/users/$userId
+ * Used for non-system user policies and profile owner files.
+ */
+ default File getUserSystemDirectory(int userId) {
+ return Environment.getUserSystemDirectory(userId);
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
index 19a7659..7b7a454 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
@@ -16,7 +16,6 @@
package com.android.server.devicepolicy;
-import android.annotation.Nullable;
import android.app.admin.DeviceAdminInfo;
import android.content.ComponentName;
@@ -30,12 +29,6 @@
*/
public interface PolicyUpgraderDataProvider {
/**
- * Returns true if the provided {@code userId} is a device owner. May affect some policy
- * defaults.
- */
- boolean isDeviceOwner(int userId, ComponentName who);
-
- /**
* Returns true if the storage manager indicates file-based encryption is enabled.
*/
boolean storageManagerIsFileBasedEncryptionEnabled();
@@ -51,11 +44,6 @@
JournaledFile makePoliciesVersionJournaledFile(int userId);
/**
- * Returns the {@code ComponentName} of the owner component for a user.
- */
- @Nullable ComponentName getOwnerComponent(int userId);
-
- /**
* Returns a function which provides the component name and device admin info for a given
* user.
*/
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
index f0ceb31..7556d69 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
@@ -16,10 +16,12 @@
package com.android.server.devicepolicy;
+import android.content.ComponentName;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.JournaledFile;
import java.io.File;
@@ -50,16 +52,16 @@
private static final String LOG_TAG = "DevicePolicyManager";
private static final boolean VERBOSE_LOG = DevicePolicyManagerService.VERBOSE_LOG;
private final PolicyUpgraderDataProvider mProvider;
+ private final PolicyPathProvider mPathProvider;
- public PolicyVersionUpgrader(PolicyUpgraderDataProvider provider) {
+ @VisibleForTesting
+ PolicyVersionUpgrader(PolicyUpgraderDataProvider provider, PolicyPathProvider pathProvider) {
mProvider = provider;
+ mPathProvider = pathProvider;
}
-
/**
* Performs the upgrade steps for all users on the system.
*
- * @param allUsers List of all user IDs on the system, including disabled users, as well as
- * managed profile user IDs.
* @param dpmsVersion The version to upgrade to.
*/
public void upgradePolicy(int dpmsVersion) {
@@ -71,11 +73,13 @@
}
final int[] allUsers = mProvider.getUsersForUpgrade();
+ final OwnersData ownersData = loadOwners(allUsers);
- //NOTE: The current version is provided in case the XML file format changes in a
+ // NOTE: The current version is provided in case the XML file format changes in a
// non-backwards-compatible way, so that DeviceAdminData could load it with
// old tags, for example.
- final SparseArray<DevicePolicyData> allUsersData = loadAllUsersData(allUsers, oldVersion);
+ final SparseArray<DevicePolicyData> allUsersData =
+ loadAllUsersData(allUsers, oldVersion, ownersData);
int currentVersion = oldVersion;
if (currentVersion == 0) {
@@ -96,7 +100,9 @@
continue;
}
for (ActiveAdmin admin : userData.mAdminList) {
- if (mProvider.isDeviceOwner(userId, admin.info.getComponent())) {
+ if (ownersData.mDeviceOwnerUserId == userId
+ && ownersData.mDeviceOwner != null
+ && ownersData.mDeviceOwner.admin.equals(admin.info.getComponent())) {
Slog.i(LOG_TAG, String.format(
"Marking Device Owner in user %d for permission grant ", userId));
admin.mAdminCanGrantSensorsPermissions = true;
@@ -106,15 +112,26 @@
currentVersion = 2;
}
- writePoliciesAndVersion(allUsers, allUsersData, currentVersion);
+ writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion);
+ }
+
+ private OwnersData loadOwners(int[] allUsers) {
+ OwnersData ownersData = new OwnersData(mPathProvider);
+ ownersData.load(allUsers);
+ return ownersData;
}
private void writePoliciesAndVersion(int[] allUsers, SparseArray<DevicePolicyData> allUsersData,
- int currentVersion) {
+ OwnersData ownersData, int currentVersion) {
boolean allWritesSuccessful = true;
for (int user : allUsers) {
- allWritesSuccessful = allWritesSuccessful && writeDataForUser(user,
- allUsersData.get(user));
+ allWritesSuccessful =
+ allWritesSuccessful && writeDataForUser(user, allUsersData.get(user));
+ }
+
+ allWritesSuccessful = allWritesSuccessful && ownersData.writeDeviceOwner();
+ for (int user : allUsers) {
+ allWritesSuccessful = allWritesSuccessful && ownersData.writeProfileOwner(user);
}
if (allWritesSuccessful) {
@@ -125,21 +142,29 @@
}
}
- private SparseArray<DevicePolicyData> loadAllUsersData(int[] allUsers, int loadVersion) {
+ private SparseArray<DevicePolicyData> loadAllUsersData(int[] allUsers, int loadVersion,
+ OwnersData ownersData) {
final SparseArray<DevicePolicyData> allUsersData = new SparseArray<>();
for (int user: allUsers) {
- allUsersData.append(user, loadDataForUser(user, loadVersion));
+ ComponentName owner = null;
+ if (ownersData.mDeviceOwnerUserId == user && ownersData.mDeviceOwner != null) {
+ owner = ownersData.mDeviceOwner.admin;
+ } else if (ownersData.mProfileOwners.containsKey(user)) {
+ owner = ownersData.mProfileOwners.get(user).admin;
+ }
+ allUsersData.append(user, loadDataForUser(user, loadVersion, owner));
}
return allUsersData;
}
- private DevicePolicyData loadDataForUser(int userId, int loadVersion) {
+ private DevicePolicyData loadDataForUser(
+ int userId, int loadVersion, ComponentName ownerComponent) {
DevicePolicyData policy = new DevicePolicyData(userId);
DevicePolicyData.load(policy,
!mProvider.storageManagerIsFileBasedEncryptionEnabled(),
mProvider.makeDevicePoliciesJournaledFile(userId),
mProvider.getAdminInfoSupplier(userId),
- mProvider.getOwnerComponent(userId));
+ ownerComponent);
return policy;
}
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 8aa9f60..994a767 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -238,7 +238,7 @@
}
}
- // called from Device.close()
+ // called from Device.closeLocked()
public void removeDeviceConnection(DeviceConnection connection) {
mDeviceConnections.remove(connection.getToken());
if (mListeners.size() == 0 && mDeviceConnections.size() == 0) {
@@ -294,12 +294,6 @@
}
for (DeviceConnection connection : mDeviceConnections.values()) {
- if (connection.getDevice().getDeviceInfo().getType()
- == MidiDeviceInfo.TYPE_USB) {
- synchronized (mUsbMidiLock) {
- removeUsbMidiDeviceLocked(connection.getDevice().getDeviceInfo());
- }
- }
connection.getDevice().removeDeviceConnection(connection);
}
}
@@ -541,6 +535,13 @@
synchronized (mDeviceConnections) {
mDeviceConnections.remove(connection);
+ if (connection.getDevice().getDeviceInfo().getType()
+ == MidiDeviceInfo.TYPE_USB) {
+ synchronized (mUsbMidiLock) {
+ removeUsbMidiDeviceLocked(connection.getDevice().getDeviceInfo());
+ }
+ }
+
if (mDeviceConnections.size() == 0 && mServiceConnection != null) {
mContext.unbindService(mServiceConnection);
mServiceConnection = null;
@@ -559,6 +560,12 @@
public void closeLocked() {
synchronized (mDeviceConnections) {
for (DeviceConnection connection : mDeviceConnections) {
+ if (connection.getDevice().getDeviceInfo().getType()
+ == MidiDeviceInfo.TYPE_USB) {
+ synchronized (mUsbMidiLock) {
+ removeUsbMidiDeviceLocked(connection.getDevice().getDeviceInfo());
+ }
+ }
connection.getClient().removeDeviceConnection(connection);
}
mDeviceConnections.clear();
@@ -1401,6 +1408,8 @@
String deviceName = extractUsbDeviceName(name);
String tagName = extractUsbDeviceTag(name);
+ Log.i(TAG, "Checking " + deviceName + " " + tagName);
+
// Only one MIDI 2.0 device can be used at once.
// Multiple MIDI 1.0 devices can be used at once.
if (mUsbMidiUniversalDeviceInUse.contains(deviceName)
@@ -1420,6 +1429,8 @@
String deviceName = extractUsbDeviceName(name);
String tagName = extractUsbDeviceTag(name);
+ Log.i(TAG, "Adding " + deviceName + " " + tagName);
+
if ((tagName).equals(MIDI_UNIVERSAL_STRING)) {
mUsbMidiUniversalDeviceInUse.add(deviceName);
} else if ((tagName).equals(MIDI_LEGACY_STRING)) {
@@ -1437,6 +1448,8 @@
String deviceName = extractUsbDeviceName(name);
String tagName = extractUsbDeviceTag(name);
+ Log.i(TAG, "Removing " + deviceName + " " + tagName);
+
if ((tagName).equals(MIDI_UNIVERSAL_STRING)) {
mUsbMidiUniversalDeviceInUse.remove(deviceName);
} else if ((tagName).equals(MIDI_LEGACY_STRING)) {
diff --git a/services/proguard.flags b/services/proguard.flags
index 425da6c..bad02b4 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -33,6 +33,11 @@
public <init>(...);
}
+# Accessed from com.android.compos APEX
+-keep,allowoptimization,allowaccessmodification class com.android.internal.art.ArtStatsLog {
+ public static void write(...);
+}
+
# Binder interfaces
-keep,allowoptimization,allowaccessmodification class * extends android.os.IInterface
-keep,allowoptimization,allowaccessmodification class * extends android.os.IHwInterface
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index ac54293..009dae5 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -582,6 +582,7 @@
DeviceConfigSession<Boolean> bgCurrentDrainMonitor = null;
DeviceConfigSession<Long> bgCurrentDrainWindow = null;
+ DeviceConfigSession<Long> bgCurrentDrainInteractionGracePeriod = null;
DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null;
DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null;
DeviceConfigSession<Boolean> bgPromptFgsWithNotiToBgRestricted = null;
@@ -617,6 +618,14 @@
R.integer.config_bg_current_drain_window));
bgCurrentDrainWindow.set(windowMs);
+ bgCurrentDrainInteractionGracePeriod = new DeviceConfigSession<>(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD,
+ DeviceConfig::getLong,
+ (long) mContext.getResources().getInteger(
+ R.integer.config_bg_current_drain_window));
+ bgCurrentDrainInteractionGracePeriod.set(windowMs);
+
bgCurrentDrainRestrictedBucketThreshold = new DeviceConfigSession<>(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET,
@@ -768,6 +777,32 @@
clearInvocations(mInjector.getAppStandbyInternal());
+ // It won't be restricted since user just interacted with it.
+ runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
+ zeros, new double[]{0, restrictBucketThresholdMah - 1},
+ zeros, new double[]{restrictBucketThresholdMah + 1, 0},
+ () -> {
+ doReturn(mCurrentTimeMillis).when(stats).getStatsStartTimestamp();
+ doReturn(mCurrentTimeMillis + windowMs)
+ .when(stats).getStatsEndTimestamp();
+ mCurrentTimeMillis += windowMs + 1;
+ try {
+ listener.verify(timeout, testUid, testPkgName,
+ RESTRICTION_LEVEL_RESTRICTED_BUCKET);
+ fail("There shouldn't be any level change events");
+ } catch (Exception e) {
+ // Expected.
+ }
+ verify(mInjector.getAppStandbyInternal(), never()).restrictApp(
+ eq(testPkgName),
+ eq(testUser),
+ anyInt(), anyInt());
+ });
+
+ // Sleep a while.
+ Thread.sleep(windowMs);
+ clearInvocations(mInjector.getAppStandbyInternal());
+ // Now it should have been restricted.
runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
zeros, new double[]{0, restrictBucketThresholdMah - 1},
zeros, new double[]{restrictBucketThresholdMah + 1, 0},
@@ -1061,6 +1096,7 @@
} finally {
closeIfNotNull(bgCurrentDrainMonitor);
closeIfNotNull(bgCurrentDrainWindow);
+ closeIfNotNull(bgCurrentDrainInteractionGracePeriod);
closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold);
closeIfNotNull(bgCurrentDrainBgRestrictedThreshold);
closeIfNotNull(bgPromptFgsWithNotiToBgRestricted);
@@ -1610,6 +1646,7 @@
DeviceConfigSession<Boolean> bgCurrentDrainMonitor = null;
DeviceConfigSession<Long> bgCurrentDrainWindow = null;
+ DeviceConfigSession<Long> bgCurrentDrainInteractionGracePeriod = null;
DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null;
DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null;
DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketHighThreshold = null;
@@ -1655,6 +1692,14 @@
R.integer.config_bg_current_drain_window));
bgCurrentDrainWindow.set(windowMs);
+ bgCurrentDrainInteractionGracePeriod = new DeviceConfigSession<>(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_INTERACTION_GRACE_PERIOD,
+ DeviceConfig::getLong,
+ (long) mContext.getResources().getInteger(
+ R.integer.config_bg_current_drain_window));
+ bgCurrentDrainInteractionGracePeriod.set(windowMs);
+
bgCurrentDrainRestrictedBucketThreshold = new DeviceConfigSession<>(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
AppBatteryPolicy.KEY_BG_CURRENT_DRAIN_THRESHOLD_TO_RESTRICTED_BUCKET,
@@ -2176,6 +2221,7 @@
} finally {
closeIfNotNull(bgCurrentDrainMonitor);
closeIfNotNull(bgCurrentDrainWindow);
+ closeIfNotNull(bgCurrentDrainInteractionGracePeriod);
closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold);
closeIfNotNull(bgCurrentDrainBgRestrictedThreshold);
closeIfNotNull(bgCurrentDrainRestrictedBucketHighThreshold);
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 2f68306..8d59dce 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -30,6 +30,7 @@
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
@@ -1591,6 +1592,69 @@
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_TreatLikeVisFGS() {
+ final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+ MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+ final ProcessRecord client1 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+ MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+ final ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID,
+ MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false));
+ client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+ client2.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+
+ final ServiceRecord s1 = bindService(app1, client1, null,
+ Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE, mock(IBinder.class));
+ final ServiceRecord s2 = bindService(app2, client2, null,
+ Context.BIND_IMPORTANT, mock(IBinder.class));
+
+ sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
+ sService.mOomAdjuster.updateOomAdjLocked(app2, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, VISIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ assertProcStates(app2, PROCESS_STATE_PERSISTENT, PERSISTENT_SERVICE_ADJ,
+ SCHED_GROUP_DEFAULT);
+
+ bindService(app2, client1, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
+ mock(IBinder.class));
+ sService.mOomAdjuster.updateOomAdjLocked(app2, OomAdjuster.OOM_ADJ_REASON_NONE);
+ assertProcStates(app2, PROCESS_STATE_PERSISTENT, PERSISTENT_SERVICE_ADJ,
+ SCHED_GROUP_DEFAULT);
+
+ s1.getConnections().clear();
+ s2.getConnections().clear();
+ client1.mState.setMaxAdj(UNKNOWN_ADJ);
+ client2.mState.setMaxAdj(UNKNOWN_ADJ);
+ client1.mServices.setHasForegroundServices(true, 0);
+ client2.mState.setHasOverlayUi(true);
+
+ bindService(app1, client1, s1, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
+ mock(IBinder.class));
+ bindService(app2, client2, s2, Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE,
+ mock(IBinder.class));
+
+ sService.mOomAdjuster.updateOomAdjLocked(app1, OomAdjuster.OOM_ADJ_REASON_NONE);
+ sService.mOomAdjuster.updateOomAdjLocked(app2, OomAdjuster.OOM_ADJ_REASON_NONE);
+
+ assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ assertProcStates(app2, PROCESS_STATE_IMPORTANT_FOREGROUND, PERCEPTIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+
+ client2.mState.setHasOverlayUi(false);
+ doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState();
+ doReturn(client2).when(sService).getTopApp();
+ sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+
+ sService.mOomAdjuster.updateOomAdjLocked(app2, OomAdjuster.OOM_ADJ_REASON_NONE);
+ assertProcStates(app2, PROCESS_STATE_BOUND_TOP, VISIBLE_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_UidIdle_StopService() {
final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 55745cd..63939c9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -195,8 +195,9 @@
val packageParser: PackageParser2 = mock()
val keySetManagerService: KeySetManagerService = mock()
val packageAbiHelper: PackageAbiHelper = mock()
+ val appsFilterSnapshot: AppsFilterSnapshotImpl = mock()
val appsFilter: AppsFilterImpl = mock {
- whenever(snapshot()) { this@mock }
+ whenever(snapshot()) { appsFilterSnapshot }
}
val dexManager: DexManager = mock()
val installer: Installer = mock()
@@ -332,6 +333,9 @@
// everything visible by default
whenever(mocks.appsFilter.shouldFilterApplication(any(PackageDataSnapshot::class.java),
anyInt(), nullable(), nullable(), anyInt())) { false }
+ whenever(mocks.appsFilterSnapshot.shouldFilterApplication(
+ any(PackageDataSnapshot::class.java),
+ anyInt(), nullable(), nullable(), anyInt())) { false }
val displayManager: DisplayManager = mock()
whenever(mocks.context.getSystemService(DisplayManager::class.java))
diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_owner_2.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_owner_2.xml
new file mode 100644
index 0000000..fb0b02e
--- /dev/null
+++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_owner_2.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<root>
+ <device-owner name="" component="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1" isPoOrganizationOwnedDevice="true" />
+ <!-- userId is substituted by the test -->
+ <device-owner-context userId="0" />
+</root>
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 08df438..19df5a2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -89,8 +89,10 @@
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
+import android.util.Pair;
import android.view.Display;
import android.view.KeyEvent;
+import android.view.MagnificationSpec;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
@@ -145,6 +147,8 @@
private static final int USER_ID = 1;
private static final int USER_ID2 = 2;
private static final int INTERACTION_ID = 199;
+ private static final Pair<float[], MagnificationSpec> FAKE_MATRIX_AND_MAG_SPEC =
+ new Pair<>(new float[9], new MagnificationSpec());
private static final int PID = Process.myPid();
private static final long TID = Process.myTid();
private static final int UID = Process.myUid();
@@ -188,6 +192,8 @@
.thenReturn(mMockFingerprintGestureDispatcher);
when(mMockSystemSupport.getMagnificationProcessor())
.thenReturn(mMockMagnificationProcessor);
+ when(mMockSystemSupport.getWindowTransformationMatrixAndMagnificationSpec(anyInt()))
+ .thenReturn(FAKE_MATRIX_AND_MAG_SPEC);
PowerManager powerManager =
new PowerManager(mMockContext, mMockIPowerManager, mMockIThermalService, mHandler);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index ca9ab4f..4f4be6c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -543,7 +543,7 @@
mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1).token;
final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, eventWindowToken);
- when(mMockWindowManagerInternal.getFocusedWindowToken())
+ when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
.thenReturn(eventWindowToken);
final int noUse = 0;
@@ -679,7 +679,7 @@
mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).token;
final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, defaultFocusWinToken);
- when(mMockWindowManagerInternal.getFocusedWindowToken())
+ when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
.thenReturn(defaultFocusWinToken);
final int newFocusWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
DEFAULT_FOCUSED_INDEX + 1);
diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
index d1390c6..e68a8a0 100644
--- a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
@@ -49,10 +49,11 @@
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+ assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
// Different processes and tags should not get rate limited either.
assertFalse(mRateLimiter.shouldRateLimit("tag", "process2").shouldRateLimit());
assertFalse(mRateLimiter.shouldRateLimit("tag2", "process").shouldRateLimit());
- // The 6th entry of the same process should be rate limited.
+ // The 7th entry of the same process should be rate limited.
assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
}
@@ -64,12 +65,13 @@
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
- // The 6th entry of the same process should be rate limited.
+ assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
+ // The 7th entry of the same process should be rate limited.
assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
- // After 11 seconds there should be nothing left in the buffer and the same type of entry
+ // After 11 minutes there should be nothing left in the buffer and the same type of entry
// should not get rate limited anymore.
- mClock.setOffsetMillis(11000);
+ mClock.setOffsetMillis(11 * 60 * 1000);
assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
}
@@ -86,13 +88,15 @@
mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
assertEquals(0,
mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
+ assertEquals(0,
+ mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
assertEquals(1,
mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
assertEquals(2,
mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated());
- // After 11 seconds the rate limiting buffer will be cleared and rate limiting will stop.
- mClock.setOffsetMillis(11000);
+ // After 11 minutes the rate limiting buffer will be cleared and rate limiting will stop.
+ mClock.setOffsetMillis(11 * 60 * 1000);
// The first call after rate limiting stops will still return the number of dropped events.
assertEquals(2,
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/InputControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/InputControllerTest.java
index b4bb04d..77cbb3a 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/InputControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/InputControllerTest.java
@@ -19,22 +19,22 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.IInputManager;
-import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.view.Display;
import android.view.DisplayInfo;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.server.LocalServices;
import org.junit.Before;
@@ -44,7 +44,8 @@
import org.mockito.MockitoAnnotations;
@Presubmit
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class InputControllerTest {
@Mock
@@ -56,13 +57,16 @@
@Mock
private IInputManager mIInputManagerMock;
+ private InputManagerMockHelper mInputManagerMockHelper;
private InputController mInputController;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mInputManagerMockHelper = new InputManagerMockHelper(
+ TestableLooper.get(this), mNativeWrapperMock, mIInputManagerMock);
- doNothing().when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt());
+ doReturn(true).when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt());
LocalServices.removeServiceForTest(InputManagerInternal.class);
LocalServices.addService(InputManagerInternal.class, mInputManagerInternalMock);
@@ -72,10 +76,10 @@
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
- InputManager.resetInstance(mIInputManagerMock);
- doNothing().when(mIInputManagerMock).addUniqueIdAssociation(anyString(), anyString());
- doNothing().when(mIInputManagerMock).removeUniqueIdAssociation(anyString());
- mInputController = new InputController(new Object(), mNativeWrapperMock);
+ // Allow virtual devices to be created on the looper thread for testing.
+ final InputController.DeviceCreationThreadVerifier threadVerifier = () -> true;
+ mInputController = new InputController(new Object(), mNativeWrapperMock,
+ new Handler(TestableLooper.get(this).getLooper()), threadVerifier);
}
@Test
@@ -83,6 +87,7 @@
final IBinder deviceToken = new Binder();
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken,
/* displayId= */ 1);
+ verify(mNativeWrapperMock).openUinputMouse(eq("name"), eq(1), eq(1), anyString());
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
doReturn(1).when(mInputManagerInternalMock).getVirtualMousePointerDisplayId();
mInputController.unregisterInputDevice(deviceToken);
@@ -95,10 +100,12 @@
final IBinder deviceToken = new Binder();
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken,
/* displayId= */ 1);
+ verify(mNativeWrapperMock).openUinputMouse(eq("name"), eq(1), eq(1), anyString());
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
final IBinder deviceToken2 = new Binder();
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken2,
/* displayId= */ 2);
+ verify(mNativeWrapperMock, times(2)).openUinputMouse(eq("name"), eq(1), eq(1), anyString());
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(2));
mInputController.unregisterInputDevice(deviceToken);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java b/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java
new file mode 100644
index 0000000..aa2d97e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/InputManagerMockHelper.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.virtual;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.os.RemoteException;
+import android.testing.TestableLooper;
+import android.view.InputDevice;
+
+import org.mockito.invocation.InvocationOnMock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.IntStream;
+
+/**
+ * A test utility class used to share the logic for setting up {@link InputManager}'s callback for
+ * when a virtual input device being added.
+ */
+class InputManagerMockHelper {
+ private final TestableLooper mTestableLooper;
+ private final InputController.NativeWrapper mNativeWrapperMock;
+ private final IInputManager mIInputManagerMock;
+ private final List<InputDevice> mDevices = new ArrayList<>();
+ private IInputDevicesChangedListener mDevicesChangedListener;
+
+ InputManagerMockHelper(TestableLooper testableLooper,
+ InputController.NativeWrapper nativeWrapperMock, IInputManager iInputManagerMock)
+ throws Exception {
+ mTestableLooper = testableLooper;
+ mNativeWrapperMock = nativeWrapperMock;
+ mIInputManagerMock = iInputManagerMock;
+
+ doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputMouse(
+ anyString(), anyInt(), anyInt(), anyString());
+ doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputKeyboard(
+ anyString(), anyInt(), anyInt(), anyString());
+ doAnswer(this::handleNativeOpenInputDevice).when(mNativeWrapperMock).openUinputTouchscreen(
+ anyString(), anyInt(), anyInt(), anyString(), anyInt(), anyInt());
+
+ doAnswer(inv -> {
+ mDevicesChangedListener = inv.getArgument(0);
+ return null;
+ }).when(mIInputManagerMock).registerInputDevicesChangedListener(notNull());
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
+ doAnswer(inv -> mDevices.get(inv.getArgument(0)))
+ .when(mIInputManagerMock).getInputDevice(anyInt());
+ doNothing().when(mIInputManagerMock).addUniqueIdAssociation(anyString(), anyString());
+ doNothing().when(mIInputManagerMock).removeUniqueIdAssociation(anyString());
+
+ // Set a new instance of InputManager for testing that uses the IInputManager mock as the
+ // interface to the server.
+ InputManager.resetInstance(mIInputManagerMock);
+ }
+
+ private Void handleNativeOpenInputDevice(InvocationOnMock inv) {
+ Objects.requireNonNull(mDevicesChangedListener,
+ "InputController did not register an InputDevicesChangedListener.");
+ // We only use a subset of the fields of InputDevice in InputController.
+ final InputDevice device = new InputDevice(mDevices.size() /*id*/, 1 /*generation*/, 0,
+ inv.getArgument(0) /*name*/, inv.getArgument(1) /*vendorId*/,
+ inv.getArgument(2) /*productId*/, inv.getArgument(3) /*descriptor*/,
+ true /*isExternal*/, 0 /*sources*/, 0 /*keyboardType*/,
+ null /*keyCharacterMap*/, false /*hasVibrator*/, false /*hasMic*/,
+ false /*hasButtonUnderPad*/, false /*hasSensor*/, false /*hasBattery*/);
+ mDevices.add(device);
+ try {
+ mDevicesChangedListener.onInputDevicesChanged(
+ mDevices.stream().flatMapToInt(
+ d -> IntStream.of(d.getId(), d.getGeneration())).toArray());
+ } catch (RemoteException ignored) {
+ }
+ // Process the device added notification.
+ mTestableLooper.processAllMessages();
+ return null;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 808f8c2c..cbb9fd7 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -54,6 +54,7 @@
import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.hardware.display.DisplayManagerInternal;
+import android.hardware.input.IInputManager;
import android.hardware.input.InputManagerInternal;
import android.hardware.input.VirtualKeyEvent;
import android.hardware.input.VirtualMouseButtonEvent;
@@ -118,6 +119,7 @@
private static final int FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES = 0x00000;
private Context mContext;
+ private InputManagerMockHelper mInputManagerMockHelper;
private VirtualDeviceImpl mDeviceImpl;
private InputController mInputController;
private AssociationInfo mAssociationInfo;
@@ -146,6 +148,8 @@
private IAudioConfigChangedCallback mConfigChangedCallback;
@Mock
private ApplicationInfo mApplicationInfoMock;
+ @Mock
+ IInputManager mIInputManagerMock;
private ArraySet<ComponentName> getBlockedActivities() {
ArraySet<ComponentName> blockedActivities = new ArraySet<>();
@@ -170,13 +174,13 @@
}
@Before
- public void setUp() {
+ public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
- doNothing().when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt());
+ doReturn(true).when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt());
doNothing().when(mInputManagerInternalMock).setPointerAcceleration(anyFloat(), anyInt());
doNothing().when(mInputManagerInternalMock).setPointerIconVisible(anyBoolean(), anyInt());
LocalServices.removeServiceForTest(InputManagerInternal.class);
@@ -199,7 +203,13 @@
new Handler(TestableLooper.get(this).getLooper()));
when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
- mInputController = new InputController(new Object(), mNativeWrapperMock);
+ mInputManagerMockHelper = new InputManagerMockHelper(
+ TestableLooper.get(this), mNativeWrapperMock, mIInputManagerMock);
+ // Allow virtual devices to be created on the looper thread for testing.
+ final InputController.DeviceCreationThreadVerifier threadVerifier = () -> true;
+ mInputController = new InputController(new Object(), mNativeWrapperMock,
+ new Handler(TestableLooper.get(this).getLooper()), threadVerifier);
+
mAssociationInfo = new AssociationInfo(1, 0, null,
MacAddress.BROADCAST_ADDRESS, "", null, true, false, 0, 0);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index 8bb619f..673b696 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -289,12 +289,11 @@
private void prepareAdmin1AsDo() throws Exception {
setUpPackageManagerForAdmin(admin1, UserHandle.getUid(USER_SYSTEM, COPE_ADMIN1_APP_ID));
final int xmlResource = R.raw.comp_policies_primary;
+ File dataSystemDirectory = getServices().pathProvider.getDataSystemDirectory();
writeInputStreamToFile(getRawStream(xmlResource),
- (new File(getServices().systemUserDataDir, "device_policies.xml"))
- .getAbsoluteFile());
+ (new File(dataSystemDirectory, "device_policies.xml")).getAbsoluteFile());
writeInputStreamToFile(getRawStream(R.raw.comp_device_owner),
- (new File(getServices().dataDir, "device_owner_2.xml"))
- .getAbsoluteFile());
+ (new File(dataSystemDirectory, "device_owner_2.xml")).getAbsoluteFile());
}
private void prepareAdmin1AsPo(int profileUserId, int targetSdk) throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 2dbf728..c771998 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -55,8 +55,8 @@
import com.android.server.PersistentDataBlockManagerInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.pm.UserManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
-import java.io.File;
import java.io.IOException;
import java.util.Map;
@@ -64,45 +64,16 @@
* Overrides {@link #DevicePolicyManagerService} for dependency injection.
*/
public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerService {
- /**
- * Overrides {@link #Owners} for dependency injection.
- */
- public static class OwnersTestable extends Owners {
-
- public OwnersTestable(MockSystemServices services) {
- super(services.userManager, services.userManagerInternal,
- services.packageManagerInternal, services.activityTaskManagerInternal,
- services.activityManagerInternal, new MockInjector(services));
- }
-
- static class MockInjector extends Injector {
- private final MockSystemServices mServices;
-
- private MockInjector(MockSystemServices services) {
- mServices = services;
- }
-
- @Override
- File environmentGetDataSystemDirectory() {
- return mServices.dataDir;
- }
-
- @Override
- File environmentGetUserSystemDirectory(int userId) {
- return mServices.environment.getUserSystemDirectory(userId);
- }
- }
- }
-
public final DpmMockContext context;
- protected final MockInjector mMockInjector;
+ public final MockInjector mMockInjector;
public DevicePolicyManagerServiceTestable(MockSystemServices services, DpmMockContext context) {
- this(new MockInjector(services, context));
+ this(new MockInjector(services, context), services.pathProvider);
}
- private DevicePolicyManagerServiceTestable(MockInjector injector) {
- super(unregisterLocalServices(injector));
+ private DevicePolicyManagerServiceTestable(
+ MockInjector injector, PolicyPathProvider pathProvider) {
+ super(unregisterLocalServices(injector), pathProvider);
mMockInjector = injector;
this.context = injector.context;
}
@@ -151,11 +122,6 @@
}
@Override
- Owners newOwners() {
- return new OwnersTestable(services);
- }
-
- @Override
UserManager getUserManager() {
return services.userManager;
}
@@ -216,6 +182,11 @@
}
@Override
+ ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+ return services.activityTaskManagerInternal;
+ }
+
+ @Override
IPackageManager getIPackageManager() {
return services.ipackageManager;
}
@@ -269,11 +240,6 @@
}
@Override
- String getDevicePolicyFilePathForSystemUser() {
- return services.systemUserDataDir.getAbsolutePath() + "/";
- }
-
- @Override
long binderClearCallingIdentity() {
return context.binder.clearCallingIdentity();
}
@@ -309,11 +275,6 @@
}
@Override
- File environmentGetUserSystemDirectory(int userId) {
- return services.environment.getUserSystemDirectory(userId);
- }
-
- @Override
void powerManagerGoToSleep(long time, int reason, int flags) {
services.powerManager.goToSleep(time, reason, flags);
}
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 545361c..0fc201e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -8613,8 +8613,7 @@
}
private File getProfileOwnerPoliciesFile() {
- File parentDir = dpms.mMockInjector.environmentGetUserSystemDirectory(
- CALLER_USER_HANDLE);
+ File parentDir = getServices().pathProvider.getUserSystemDirectory(CALLER_USER_HANDLE);
return getPoliciesFile(parentDir);
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 884ffce..46cc68f 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -137,6 +137,7 @@
public final PackageManager packageManager;
public final BuildMock buildMock = new BuildMock();
public final File dataDir;
+ public final PolicyPathProvider pathProvider;
public MockSystemServices(Context realContext, String name) {
dataDir = new File(realContext.getCacheDir(), name);
@@ -217,6 +218,17 @@
// System user is always running.
setUserRunning(UserHandle.USER_SYSTEM, true);
+ pathProvider = new PolicyPathProvider() {
+ @Override
+ public File getDataSystemDirectory() {
+ return new File(systemUserDataDir.getAbsolutePath());
+ }
+
+ @Override
+ public File getUserSystemDirectory(int userId) {
+ return environment.getUserSystemDirectory(userId);
+ }
+ };
}
/** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index 37ba8a4..f535fda 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -28,8 +28,6 @@
import androidx.test.runner.AndroidJUnit4;
-import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -58,7 +56,7 @@
public void loadProfileOwner() throws Exception {
getServices().addUsers(10);
- final OwnersTestable owners = new OwnersTestable(getServices());
+ final Owners owners = makeOwners();
DpmTestUtils.writeToFile(owners.getProfileOwnerFile(10),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/profile_owner_1.xml"));
@@ -76,7 +74,7 @@
@Test
public void loadDeviceOwner() throws Exception {
- final OwnersTestable owners = new OwnersTestable(getServices());
+ final Owners owners = makeOwners();
DpmTestUtils.writeToFile(owners.getDeviceOwnerFile(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/device_owner_1.xml"));
@@ -95,7 +93,7 @@
@Test
public void testDeviceOwnerType() throws Exception {
- final OwnersTestable owners = new OwnersTestable(getServices());
+ final Owners owners = makeOwners();
DpmTestUtils.writeToFile(owners.getDeviceOwnerFile(),
DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/device_owner_1.xml"));
@@ -117,4 +115,11 @@
assertThat(owners.getDeviceOwnerType(TESTDPC_PACKAGE))
.isEqualTo(DEVICE_OWNER_TYPE_FINANCED);
}
+
+ private Owners makeOwners() {
+ final MockSystemServices services = getServices();
+ return new Owners(services.userManager, services.userManagerInternal,
+ services.packageManagerInternal, services.activityTaskManagerInternal,
+ services.activityManagerInternal, services.pathProvider);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
index 834a514..9efc10c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
@@ -16,10 +16,12 @@
package com.android.server.devicepolicy;
-import static android.os.UserHandle.USER_SYSTEM;
+import static android.content.pm.UserInfo.FLAG_PRIMARY;
+import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+import static com.android.server.devicepolicy.DevicePolicyManagerService.DEVICE_POLICIES_XML;
import static com.android.server.devicepolicy.DevicePolicyManagerService.POLICIES_VERSION_XML;
-import static com.android.server.devicepolicy.DpmTestUtils.writeInputStreamToFile;
import static com.google.common.truth.Truth.assertThat;
@@ -36,7 +38,6 @@
import androidx.test.InstrumentationRegistry;
-import com.android.frameworks.servicestests.R;
import com.android.internal.util.JournaledFile;
import com.android.server.SystemService;
@@ -51,7 +52,6 @@
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
@@ -67,30 +67,18 @@
public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions";
private ComponentName mFakeAdmin;
- private static class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider {
- int mDeviceOwnerUserId;
- ComponentName mDeviceOwnerComponent = new ComponentName("", "");
+ private class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider {
boolean mIsFileBasedEncryptionEnabled;
- Map<Integer, ComponentName> mUserToComponent = new HashMap<>();
Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>();
- File mDataDir;
int[] mUsers;
@Override
- public boolean isDeviceOwner(int userId, ComponentName who) {
- return userId == mDeviceOwnerUserId && mDeviceOwnerComponent.equals(who);
- }
-
- @Override
public boolean storageManagerIsFileBasedEncryptionEnabled() {
return mIsFileBasedEncryptionEnabled;
}
private JournaledFile makeJournaledFile(int userId, String fileName) {
- File parentDir = new File(mDataDir, String.format("user%d", userId));
- if (!parentDir.exists()) {
- parentDir.mkdirs();
- }
+ File parentDir = getServices().environment.getUserSystemDirectory(userId);
final String base = new File(parentDir, fileName).getAbsolutePath();
return new JournaledFile(new File(base), new File(base + ".tmp"));
@@ -98,17 +86,12 @@
@Override
public JournaledFile makeDevicePoliciesJournaledFile(int userId) {
- return makeJournaledFile(userId, DevicePolicyManagerService.DEVICE_POLICIES_XML);
+ return makeJournaledFile(userId, DEVICE_POLICIES_XML);
}
@Override
public JournaledFile makePoliciesVersionJournaledFile(int userId) {
- return makeJournaledFile(userId, DevicePolicyManagerService.POLICIES_VERSION_XML);
- }
-
- @Override
- public ComponentName getOwnerComponent(int userId) {
- return mUserToComponent.get(userId);
+ return makeJournaledFile(userId, POLICIES_VERSION_XML);
}
@Override
@@ -125,7 +108,6 @@
private final Context mRealTestContext = InstrumentationRegistry.getTargetContext();
private FakePolicyUpgraderDataProvider mProvider;
private PolicyVersionUpgrader mUpgrader;
- private File mDataDir;
@Before
public void setUp() {
@@ -134,11 +116,7 @@
IpcDataCache.disableForTestMode();
mProvider = new FakePolicyUpgraderDataProvider();
- mUpgrader = new PolicyVersionUpgrader(mProvider);
- mDataDir = new File(mRealTestContext.getCacheDir(), "test-data");
- mDataDir.getParentFile().mkdirs();
- // Prepare provider.
- mProvider.mDataDir = mDataDir;
+ mUpgrader = new PolicyVersionUpgrader(mProvider, getServices().pathProvider);
mFakeAdmin = new ComponentName(
"com.android.frameworks.servicestests",
"com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
@@ -165,6 +143,7 @@
public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException {
final String activePasswordTag = "active-password";
mProvider.mUsers = new int[] {0, 10};
+ getServices().addUser(10, /* flags= */ 0, USER_TYPE_PROFILE_MANAGED);
writeVersionToXml(0);
for (int userId : mProvider.mUsers) {
preparePoliciesFile(userId);
@@ -185,13 +164,12 @@
throws IOException, XmlPullParserException {
final int ownerUser = 10;
mProvider.mUsers = new int[] {0, ownerUser};
+ getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
writeVersionToXml(1);
for (int userId : mProvider.mUsers) {
preparePoliciesFile(userId);
}
- mProvider.mDeviceOwnerUserId = ownerUser;
- mProvider.mDeviceOwnerComponent = mFakeAdmin;
- mProvider.mUserToComponent.put(ownerUser, mFakeAdmin);
+ prepareDeviceOwnerFile(ownerUser);
mUpgrader.upgradePolicy(2);
@@ -204,19 +182,12 @@
@Test
public void testNoStaleDataInCacheAfterUpgrade() throws Exception {
- setUpPackageManagerForAdmin(admin1, UserHandle.getUid(USER_SYSTEM, 123 /* admin app ID */));
- // Reusing COPE migration policy files there, only DO on user 0 is needed.
- writeInputStreamToFile(getRawStream(R.raw.comp_policies_primary),
- new File(getServices().systemUserDataDir, "device_policies.xml")
- .getAbsoluteFile());
- writeInputStreamToFile(getRawStream(R.raw.comp_device_owner),
- new File(getServices().dataDir, "device_owner_2.xml")
- .getAbsoluteFile());
-
- // Write policy version 0
- File versionFilePath =
- new File(getServices().systemUserDataDir, POLICIES_VERSION_XML).getAbsoluteFile();
- DpmTestUtils.writeToFile(versionFilePath, "0\n");
+ final int ownerUser = 0;
+ getServices().addUser(ownerUser, FLAG_PRIMARY, USER_TYPE_FULL_SYSTEM);
+ setUpPackageManagerForAdmin(admin1, UserHandle.getUid(ownerUser, 123 /* admin app ID */));
+ writeVersionToXml(0);
+ preparePoliciesFile(ownerUser);
+ prepareDeviceOwnerFile(ownerUser);
DevicePolicyManagerServiceTestable dpms;
final long ident = getContext().binder.clearCallingIdentity();
@@ -233,7 +204,7 @@
// DO should be marked as able to grant sensors permission during upgrade and should be
// reported as such via the API.
- assertThat(dpms.canAdminGrantSensorsPermissionsForUser(/* userId= */0)).isTrue();
+ assertThat(dpms.canAdminGrantSensorsPermissionsForUser(ownerUser)).isTrue();
}
@Test
@@ -264,9 +235,27 @@
policiesFile.commit();
}
+ private void prepareDeviceOwnerFile(int userId) throws IOException {
+ File parentDir = getServices().pathProvider.getDataSystemDirectory();
+ File doFilePath = (new File(parentDir, "device_owner_2.xml")).getAbsoluteFile();
+ android.util.Log.i("YYYYYY", "DO paath: " + doFilePath);
+ String doFileContent = DpmTestUtils.readAsset(mRealTestContext,
+ "PolicyVersionUpgraderTest/device_owner_2.xml")
+ // Substitute the right DO userId, XML in resources has 0
+ .replace("userId=\"0\"", "userId=\"" + userId + "\"");
+ DpmTestUtils.writeToFile(doFilePath, doFileContent);
+ }
+
+ private void prepareProfileOwnerFile(int userId) throws IOException {
+ File parentDir = getServices().pathProvider.getUserSystemDirectory(userId);
+ DpmTestUtils.writeToFile(
+ (new File(parentDir, "profile_owner.xml")).getAbsoluteFile(),
+ DpmTestUtils.readAsset(mRealTestContext,
+ "PolicyVersionUpgraderTest/profile_owner.xml"));
+ }
+
private String readPoliciesFile(int userId) throws IOException {
File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
- FileReader reader = new FileReader(policiesFile);
return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset());
}
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 d5612e7..6f48368 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -16,7 +16,6 @@
package com.android.server.display;
-import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY;
import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX;
@@ -58,8 +57,6 @@
import android.os.MessageQueue;
import android.os.Process;
import android.platform.test.annotations.Presubmit;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfigInterface;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayEventReceiver;
@@ -67,7 +64,6 @@
import android.view.Surface;
import android.view.SurfaceControl;
-import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.FlakyTest;
@@ -81,7 +77,6 @@
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.lights.LightsManager;
import com.android.server.sensors.SensorManagerInternal;
-import com.android.server.testutils.FakeDeviceConfigInterface;
import com.android.server.wm.WindowManagerInternal;
import com.google.common.collect.ImmutableMap;
@@ -123,7 +118,6 @@
public TestRule compatChangeRule = new PlatformCompatChangeRule();
private Context mContext;
- private FakeDeviceConfigInterface mDeviceConfig;
private final DisplayManagerService.Injector mShortMockedInjector =
new DisplayManagerService.Injector() {
@@ -146,12 +140,6 @@
return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
(String name, boolean secure) -> mMockDisplayToken);
}
-
- @NonNull
- @Override
- public DeviceConfigInterface getDeviceConfig() {
- return mDeviceConfig;
- }
}
private final DisplayManagerService.Injector mBasicInjector = new BasicInjector();
@@ -199,7 +187,6 @@
VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal);
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
- mDeviceConfig = new FakeDeviceConfigInterface();
// Disable binder caches in this process.
PropertyInvalidatedCache.disableForTestMode();
@@ -661,25 +648,6 @@
}
/**
- * Tests that specifying the VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED flag is processed correctly
- * when it is allowed by DeviceConfig.
- */
- @Test
- public void testCreateVirtualDisplay_alwaysUnlockedAllowed() {
- testCreateVirtualDisplay_alwaysUnlocked(/*deviceConfigAllows*/ true, /*flagExpected*/ true);
- }
-
- /**
- * Tests that specifying the VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED flag when DeviceConfig does
- * not allow it results in the flag being stripped from the final flags.
- */
- @Test
- public void testCreateVirtualDisplay_alwaysUnlockedDisallowed() {
- testCreateVirtualDisplay_alwaysUnlocked(
- /*deviceConfigAllows*/ false, /*flagExpected*/ false);
- }
-
- /**
* Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission
* ADD_TRUSTED_DISPLAY is granted.
*/
@@ -1198,45 +1166,6 @@
assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f);
}
- private void testCreateVirtualDisplay_alwaysUnlocked(boolean deviceConfigAllows,
- boolean flagExpected) {
- mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
- DisplayManager.DeviceConfig.KEY_ALLOW_ALWAYS_UNLOCKED_VIRTUAL_DISPLAYS,
- deviceConfigAllows ? "true" : "false", /*makeDefault*/ false);
-
- DisplayManagerService displayManager =
- new DisplayManagerService(mContext, mBasicInjector);
- registerDefaultDisplays(displayManager);
- String uniqueId = "uniqueId --- ALWAYS_UNLOCKED";
- int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP
- | DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
-
- DisplayManagerService.BinderService bs = displayManager.new BinderService();
- when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
-
- when(mContext.checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY)).thenReturn(
- PackageManager.PERMISSION_GRANTED);
- when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
- PackageManager.PERMISSION_GRANTED);
-
- final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
- VIRTUAL_DISPLAY_NAME, 600, 800, 320);
- builder.setFlags(flags);
- builder.setUniqueId(uniqueId);
-
- int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
- null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
- displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
- displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
- DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
- assertNotNull(ddi);
- if (flagExpected) {
- assertNotEquals(ddi.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED, 0);
- } else {
- assertEquals(ddi.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED, 0);
- }
- }
-
private int getDisplayIdForDisplayDevice(
DisplayManagerService displayManager,
DisplayManagerService.BinderService displayManagerBinderService,
diff --git a/services/tests/servicestests/src/com/android/server/input/InputManagerServiceTests.kt b/services/tests/servicestests/src/com/android/server/input/InputManagerServiceTests.kt
new file mode 100644
index 0000000..e78f0c7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/input/InputManagerServiceTests.kt
@@ -0,0 +1,245 @@
+/*
+ * 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.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.hardware.display.DisplayViewport
+import android.hardware.input.InputManagerInternal
+import android.os.IInputConstants
+import android.os.test.TestLooper
+import android.platform.test.annotations.Presubmit
+import android.view.Display
+import android.view.PointerIcon
+import androidx.test.InstrumentationRegistry
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.junit.MockitoJUnit
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+/**
+ * Tests for {@link InputManagerService}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:InputManagerServiceTests
+ */
+@Presubmit
+class InputManagerServiceTests {
+
+ @get:Rule
+ val rule = MockitoJUnit.rule()!!
+
+ @Mock
+ private lateinit var native: NativeInputManagerService
+
+ @Mock
+ private lateinit var wmCallbacks: InputManagerService.WindowManagerCallbacks
+
+ private lateinit var service: InputManagerService
+ private lateinit var localService: InputManagerInternal
+ private lateinit var context: Context
+ private lateinit var testLooper: TestLooper
+
+ @Before
+ fun setup() {
+ context = spy(ContextWrapper(InstrumentationRegistry.getContext()))
+ testLooper = TestLooper()
+ service =
+ InputManagerService(object : InputManagerService.Injector(context, testLooper.looper) {
+ override fun getNativeService(
+ service: InputManagerService?
+ ): NativeInputManagerService {
+ return native
+ }
+
+ override fun registerLocalService(service: InputManagerInternal?) {
+ localService = service!!
+ }
+ })
+ assertTrue("Local service must be registered", this::localService.isInitialized)
+ service.setWindowManagerCallbacks(wmCallbacks)
+ }
+
+ @Test
+ fun testPointerDisplayUpdatesWhenDisplayViewportsChanged() {
+ val displayId = 123
+ `when`(wmCallbacks.pointerDisplayId).thenReturn(displayId)
+ val viewports = listOf<DisplayViewport>()
+ localService.setDisplayViewports(viewports)
+ verify(native).setDisplayViewports(any(Array<DisplayViewport>::class.java))
+ verify(native).setPointerDisplayId(displayId)
+
+ val x = 42f
+ val y = 314f
+ service.onPointerDisplayIdChanged(displayId, x, y)
+ testLooper.dispatchNext()
+ verify(wmCallbacks).notifyPointerDisplayIdChanged(displayId, x, y)
+ }
+
+ @Test
+ fun testSetVirtualMousePointerDisplayId() {
+ // Set the virtual mouse pointer displayId, and ensure that the calling thread is blocked
+ // until the native callback happens.
+ var countDownLatch = CountDownLatch(1)
+ val overrideDisplayId = 123
+ Thread {
+ assertTrue("Setting virtual pointer display should succeed",
+ localService.setVirtualMousePointerDisplayId(overrideDisplayId))
+ countDownLatch.countDown()
+ }.start()
+ assertFalse("Setting virtual pointer display should block",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+
+ val x = 42f
+ val y = 314f
+ service.onPointerDisplayIdChanged(overrideDisplayId, x, y)
+ testLooper.dispatchNext()
+ verify(wmCallbacks).notifyPointerDisplayIdChanged(overrideDisplayId, x, y)
+ assertTrue("Native callback unblocks calling thread",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+ verify(native).setPointerDisplayId(overrideDisplayId)
+
+ // Ensure that setting the same override again succeeds immediately.
+ assertTrue("Setting the same virtual mouse pointer displayId again should succeed",
+ localService.setVirtualMousePointerDisplayId(overrideDisplayId))
+
+ // Ensure that we did not query WM for the pointerDisplayId when setting the override
+ verify(wmCallbacks, never()).pointerDisplayId
+
+ // Unset the virtual mouse pointer displayId, and ensure that we query WM for the new
+ // pointer displayId and the calling thread is blocked until the native callback happens.
+ countDownLatch = CountDownLatch(1)
+ val pointerDisplayId = 42
+ `when`(wmCallbacks.pointerDisplayId).thenReturn(pointerDisplayId)
+ Thread {
+ assertTrue("Unsetting virtual mouse pointer displayId should succeed",
+ localService.setVirtualMousePointerDisplayId(Display.INVALID_DISPLAY))
+ countDownLatch.countDown()
+ }.start()
+ assertFalse("Unsetting virtual mouse pointer displayId should block",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+
+ service.onPointerDisplayIdChanged(pointerDisplayId, x, y)
+ testLooper.dispatchNext()
+ verify(wmCallbacks).notifyPointerDisplayIdChanged(pointerDisplayId, x, y)
+ assertTrue("Native callback unblocks calling thread",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+ verify(native).setPointerDisplayId(pointerDisplayId)
+ }
+
+ @Test
+ fun testSetVirtualMousePointerDisplayId_unsuccessfulUpdate() {
+ // Set the virtual mouse pointer displayId, and ensure that the calling thread is blocked
+ // until the native callback happens.
+ val countDownLatch = CountDownLatch(1)
+ val overrideDisplayId = 123
+ Thread {
+ assertFalse("Setting virtual pointer display should be unsuccessful",
+ localService.setVirtualMousePointerDisplayId(overrideDisplayId))
+ countDownLatch.countDown()
+ }.start()
+ assertFalse("Setting virtual pointer display should block",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+
+ val x = 42f
+ val y = 314f
+ // Assume the native callback updates the pointerDisplayId to the incorrect value.
+ service.onPointerDisplayIdChanged(Display.INVALID_DISPLAY, x, y)
+ testLooper.dispatchNext()
+ verify(wmCallbacks).notifyPointerDisplayIdChanged(Display.INVALID_DISPLAY, x, y)
+ assertTrue("Native callback unblocks calling thread",
+ countDownLatch.await(100, TimeUnit.MILLISECONDS))
+ verify(native).setPointerDisplayId(overrideDisplayId)
+ }
+
+ @Test
+ fun testSetVirtualMousePointerDisplayId_competingRequests() {
+ val firstRequestSyncLatch = CountDownLatch(1)
+ doAnswer {
+ firstRequestSyncLatch.countDown()
+ }.`when`(native).setPointerDisplayId(anyInt())
+
+ val firstRequestLatch = CountDownLatch(1)
+ val firstOverride = 123
+ Thread {
+ assertFalse("Setting virtual pointer display from thread 1 should be unsuccessful",
+ localService.setVirtualMousePointerDisplayId(firstOverride))
+ firstRequestLatch.countDown()
+ }.start()
+ assertFalse("Setting virtual pointer display should block",
+ firstRequestLatch.await(100, TimeUnit.MILLISECONDS))
+
+ assertTrue("Wait for first thread's request should succeed",
+ firstRequestSyncLatch.await(100, TimeUnit.MILLISECONDS))
+
+ val secondRequestLatch = CountDownLatch(1)
+ val secondOverride = 42
+ Thread {
+ assertTrue("Setting virtual mouse pointer from thread 2 should be successful",
+ localService.setVirtualMousePointerDisplayId(secondOverride))
+ secondRequestLatch.countDown()
+ }.start()
+ assertFalse("Setting virtual mouse pointer should block",
+ secondRequestLatch.await(100, TimeUnit.MILLISECONDS))
+
+ val x = 42f
+ val y = 314f
+ // Assume the native callback updates directly to the second request.
+ service.onPointerDisplayIdChanged(secondOverride, x, y)
+ testLooper.dispatchNext()
+ verify(wmCallbacks).notifyPointerDisplayIdChanged(secondOverride, x, y)
+ assertTrue("Native callback unblocks first thread",
+ firstRequestLatch.await(100, TimeUnit.MILLISECONDS))
+ assertTrue("Native callback unblocks second thread",
+ secondRequestLatch.await(100, TimeUnit.MILLISECONDS))
+ verify(native, times(2)).setPointerDisplayId(anyInt())
+ }
+
+ @Test
+ fun onDisplayRemoved_resetAllAdditionalInputProperties() {
+ localService.setVirtualMousePointerDisplayId(10)
+ localService.setPointerIconVisible(false, 10)
+ verify(native).setPointerIconType(eq(PointerIcon.TYPE_NULL))
+ localService.setPointerAcceleration(5f, 10)
+ verify(native).setPointerAcceleration(eq(5f))
+
+ service.onDisplayRemoved(10)
+ verify(native).displayRemoved(eq(10))
+ verify(native).setPointerIconType(eq(PointerIcon.TYPE_NOT_SPECIFIED))
+ verify(native).setPointerAcceleration(
+ eq(IInputConstants.DEFAULT_POINTER_ACCELERATION.toFloat()))
+
+ localService.setVirtualMousePointerDisplayId(10)
+ verify(native).setPointerDisplayId(eq(10))
+ verifyNoMoreInteractions(native)
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index a227cd3..035249e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -70,6 +70,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -516,6 +517,7 @@
}
}
+ @Ignore("Causing breakages so ignoring to resolve, b/231667368")
@Test
public void initRecoveryService_alwaysUpdatesCertsWhenTestRootCertIsUsed() throws Exception {
int uid = Binder.getCallingUid();
@@ -539,6 +541,7 @@
testRootCertAlias)).isEqualTo(TestData.getInsecureCertPathForEndpoint2());
}
+ @Ignore("Causing breakages so ignoring to resolve, b/231667368")
@Test
public void initRecoveryService_updatesCertsIndependentlyForDifferentRoots() throws Exception {
int uid = Binder.getCallingUid();
diff --git a/services/tests/servicestests/src/com/android/server/logcat/LogcatManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/logcat/LogcatManagerServiceTest.java
new file mode 100644
index 0000000..f330017
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/logcat/LogcatManagerServiceTest.java
@@ -0,0 +1,322 @@
+/*
+ * 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.logcat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.content.ContextWrapper;
+import android.os.ILogd;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.test.TestLooper;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.LocalServices;
+import com.android.server.logcat.LogcatManagerService.Injector;
+import com.android.server.testutils.OffsettableClock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.function.Supplier;
+
+/**
+ * Tests for {@link com.android.server.logcat.LogcatManagerService}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:LogcatManagerServiceTest
+ */
+@SuppressWarnings("GuardedBy")
+public class LogcatManagerServiceTest {
+ private static final String APP1_PACKAGE_NAME = "app1";
+ private static final int APP1_UID = 10001;
+ private static final int APP1_GID = 10001;
+ private static final int APP1_PID = 10001;
+ private static final String APP2_PACKAGE_NAME = "app2";
+ private static final int APP2_UID = 10002;
+ private static final int APP2_GID = 10002;
+ private static final int APP2_PID = 10002;
+ private static final int FD1 = 10;
+ private static final int FD2 = 11;
+
+ @Mock
+ private ActivityManagerInternal mActivityManagerInternalMock;
+ @Mock
+ private ILogd mLogdMock;
+
+ private LogcatManagerService mService;
+ private LogcatManagerService.LogcatManagerServiceInternal mLocalService;
+ private ContextWrapper mContextSpy;
+ private OffsettableClock mClock;
+ private TestLooper mTestLooper;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
+ mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
+ mClock = new OffsettableClock.Stopped();
+ mTestLooper = new TestLooper(mClock::now);
+
+ when(mActivityManagerInternalMock.getPackageNameByPid(APP1_PID)).thenReturn(
+ APP1_PACKAGE_NAME);
+ when(mActivityManagerInternalMock.getPackageNameByPid(APP2_PID)).thenReturn(
+ APP2_PACKAGE_NAME);
+
+ mService = new LogcatManagerService(mContextSpy, new Injector() {
+ @Override
+ protected Supplier<Long> createClock() {
+ return mClock::now;
+ }
+
+ @Override
+ protected Looper getLooper() {
+ return mTestLooper.getLooper();
+ }
+
+ @Override
+ protected ILogd getLogdService() {
+ return mLogdMock;
+ }
+ });
+ mLocalService = mService.getLocalService();
+ mService.onStart();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ }
+
+ /**
+ * Creates a mock and registers it to {@link LocalServices}.
+ */
+ private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+ LocalServices.removeServiceForTest(clazz);
+ LocalServices.addService(clazz, mock);
+ }
+
+ @Test
+ public void test_RequestFromBackground_DeclinedWithoutPrompt() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_RECEIVER);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mContextSpy, never()).startActivityAsUser(any(), any());
+ }
+
+ @Test
+ public void test_RequestFromForegroundService_DeclinedWithoutPrompt() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mContextSpy, never()).startActivityAsUser(any(), any());
+ }
+
+ @Test
+ public void test_RequestFromTop_ShowsPrompt() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void test_RequestFromTop_NoInteractionWithPrompt_DeclinesAfterTimeout()
+ throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+
+ advanceTime(LogcatManagerService.PENDING_CONFIRMATION_TIMEOUT_MILLIS);
+
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ }
+
+ @Test
+ public void test_RequestFromTop_Approved() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+
+ mLocalService.approveAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock, times(1)).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ }
+
+ @Test
+ public void test_RequestFromTop_Declined() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+
+ mLocalService.declineAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, times(1)).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ }
+
+ @Test
+ public void test_RequestFromTop_MultipleRequestsApprovedTogether() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD2);
+ mTestLooper.dispatchAll();
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ verify(mLogdMock, never()).approve(eq(APP1_UID), eq(APP1_GID), eq(APP1_PID), anyInt());
+ verify(mLogdMock, never()).decline(eq(APP1_UID), eq(APP1_GID), eq(APP1_PID), anyInt());
+
+ mLocalService.approveAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock, times(1)).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, times(1)).approve(APP1_UID, APP1_GID, APP1_PID, FD2);
+ verify(mLogdMock, never()).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).decline(APP1_UID, APP1_GID, APP1_PID, FD2);
+ }
+
+ @Test
+ public void test_RequestFromTop_MultipleRequestsDeclinedTogether() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD2);
+ mTestLooper.dispatchAll();
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ verify(mLogdMock, never()).approve(eq(APP1_UID), eq(APP1_GID), eq(APP1_PID), anyInt());
+ verify(mLogdMock, never()).decline(eq(APP1_UID), eq(APP1_GID), eq(APP1_PID), anyInt());
+
+ mLocalService.declineAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ verify(mLogdMock, times(1)).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, times(1)).decline(APP1_UID, APP1_GID, APP1_PID, FD2);
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD2);
+ }
+
+ @Test
+ public void test_RequestFromTop_Approved_DoesNotShowPromptAgain() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ mLocalService.approveAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD2);
+ mTestLooper.dispatchAll();
+
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ verify(mLogdMock, times(1)).approve(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, times(1)).approve(APP1_UID, APP1_GID, APP1_PID, FD2);
+ verify(mLogdMock, never()).decline(APP1_UID, APP1_GID, APP1_PID, FD2);
+ }
+
+ @Test
+ public void test_RequestFromTop_Declined_DoesNotShowPromptAgain() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ mLocalService.declineAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD2);
+ mTestLooper.dispatchAll();
+
+ verify(mContextSpy, times(1)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ verify(mLogdMock, times(1)).decline(APP1_UID, APP1_GID, APP1_PID, FD1);
+ verify(mLogdMock, times(1)).decline(APP1_UID, APP1_GID, APP1_PID, FD2);
+ verify(mLogdMock, never()).approve(APP1_UID, APP1_GID, APP1_PID, FD2);
+ }
+
+ @Test
+ public void test_RequestFromTop_Approved_ShowsPromptForDifferentClient() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ when(mActivityManagerInternalMock.getUidProcessState(APP2_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ mLocalService.approveAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ mService.getBinderService().startThread(APP2_UID, APP2_GID, APP2_PID, FD2);
+ mTestLooper.dispatchAll();
+
+ verify(mContextSpy, times(2)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ verify(mLogdMock, never()).decline(APP2_UID, APP2_GID, APP2_PID, FD2);
+ verify(mLogdMock, never()).approve(APP2_UID, APP2_GID, APP2_PID, FD2);
+ }
+
+ @Test
+ public void test_RequestFromTop_Approved_ShowPromptAgainAfterTimeout() throws Exception {
+ when(mActivityManagerInternalMock.getUidProcessState(APP1_UID)).thenReturn(
+ ActivityManager.PROCESS_STATE_TOP);
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+ mLocalService.declineAccessForClient(APP1_UID, APP1_PACKAGE_NAME);
+ mTestLooper.dispatchAll();
+
+ advanceTime(LogcatManagerService.STATUS_EXPIRATION_TIMEOUT_MILLIS);
+
+ mService.getBinderService().startThread(APP1_UID, APP1_GID, APP1_PID, FD1);
+ mTestLooper.dispatchAll();
+
+ verify(mContextSpy, times(2)).startActivityAsUser(any(), eq(UserHandle.SYSTEM));
+ }
+
+ private void advanceTime(long timeMs) {
+ mClock.fastForward(timeMs);
+ mTestLooper.dispatchAll();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
index c43e6ab..7974718 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java
@@ -99,7 +99,7 @@
}
@Mock
- AppsFilterImpl.FeatureConfig mFeatureConfigMock;
+ FeatureConfig mFeatureConfigMock;
@Mock
PackageDataSnapshot mSnapshot;
@Mock
@@ -1283,6 +1283,7 @@
@Test
public void testAppsFilterRead() throws Exception {
+ when(mFeatureConfigMock.snapshot()).thenReturn(mFeatureConfigMock);
final AppsFilterImpl appsFilter =
new AppsFilterImpl(mFeatureConfigMock, new String[]{}, false, null,
mMockExecutor);
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 4094377..fdf9354 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1975,7 +1975,7 @@
if (si == null) {
return null;
}
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
return new File(si.getBitmapPath()).getName();
}
@@ -1984,7 +1984,7 @@
if (si == null) {
return null;
}
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
return new File(si.getBitmapPath()).getAbsolutePath();
}
@@ -2139,7 +2139,7 @@
}
protected boolean bitmapDirectoryExists(String packageName, int userId) {
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
final File path = new File(mService.getUserBitmapFilePath(userId), packageName);
return path.isDirectory();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 411b521..867890f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -1040,7 +1040,7 @@
dumpsysOnLogcat();
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
// Check files and directories.
// Package 3 has no bitmaps, so we don't create a directory.
assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
@@ -1096,7 +1096,7 @@
makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "3").createNewFile();
makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "4").createNewFile();
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
"a.b.c", "d.e.f");
@@ -1111,7 +1111,7 @@
// The below check is the same as above, except this time USER_0 use the CALLING_PACKAGE_3
// directory.
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3);
assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
@@ -1390,7 +1390,7 @@
.setIcon(Icon.createWithContentUri("test_uri"))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconUri());
@@ -1402,13 +1402,13 @@
.setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconResource());
assertEquals(R.drawable.black_32x32, si.getIconResourceId());
});
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
@@ -1419,7 +1419,7 @@
getTestContext().getResources(), R.drawable.black_64x64)))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconFile());
@@ -1437,7 +1437,7 @@
getTestContext().getResources(), R.drawable.black_64x64)))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconFile());
@@ -1451,7 +1451,7 @@
.setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconResource());
@@ -1463,7 +1463,7 @@
.setIcon(Icon.createWithContentUri("test_uri"))
.build()
)));
- mService.waitForBitmapSaves();
+ mService.waitForBitmapSavesForTest();
assertWith(getCallerShortcuts())
.forShortcutWithId("s1", si -> {
assertTrue(si.hasIconUri());
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 f2495e1..9ff7d69 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -71,7 +71,6 @@
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerSaveState;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.provider.Settings;
@@ -144,6 +143,7 @@
@Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock;
@Mock private SystemPropertiesWrapper mSystemPropertiesMock;
@Mock private AppOpsManager mAppOpsManagerMock;
+ @Mock private LowPowerStandbyController mLowPowerStandbyControllerMock;
@Mock
private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
@@ -298,8 +298,7 @@
@Override
LowPowerStandbyController createLowPowerStandbyController(Context context,
Looper looper) {
- return new LowPowerStandbyController(context, mTestLooper.getLooper(),
- SystemClock::elapsedRealtime);
+ return mLowPowerStandbyControllerMock;
}
@Override
@@ -316,7 +315,6 @@
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.removeServiceForTest(BatteryManagerInternal.class);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
- LocalServices.removeServiceForTest(LowPowerStandbyControllerInternal.class);
FakeSettingsProvider.clearSettingsProvider();
}
@@ -1888,6 +1886,18 @@
assertThat(wakeLock.mDisabled).isFalse();
}
+ @Test
+ public void testSetLowPowerStandbyActiveDuringMaintenance_redirectsCallToNativeWrapper() {
+ createService();
+ startSystem();
+
+ mService.getBinderServiceInstance().setLowPowerStandbyActiveDuringMaintenance(true);
+ verify(mLowPowerStandbyControllerMock).setActiveDuringMaintenance(true);
+
+ mService.getBinderServiceInstance().setLowPowerStandbyActiveDuringMaintenance(false);
+ verify(mLowPowerStandbyControllerMock).setActiveDuringMaintenance(false);
+ }
+
private WakeLock acquireWakeLock(String tag, int flags) {
IBinder token = new Binder();
String packageName = "pkg.name";
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 20486b3..8167b44 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -454,14 +454,14 @@
+ " <library \n"
+ " name=\"foo\"\n"
+ " file=\"" + mFooJar + "\"\n"
- + " on-bootclasspath-before=\"Q\"\n"
+ + " on-bootclasspath-before=\"A\"\n"
+ " on-bootclasspath-since=\"W\"\n"
+ " />\n\n"
+ " </permissions>";
parseSharedLibraries(contents);
assertFooIsOnlySharedLibrary();
SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
- assertThat(entry.onBootclasspathBefore).isEqualTo("Q");
+ assertThat(entry.onBootclasspathBefore).isEqualTo("A");
assertThat(entry.onBootclasspathSince).isEqualTo("W");
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java
index e9515fa..ffc0dcd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java
@@ -82,8 +82,6 @@
ImportanceExtractor extractor = new ImportanceExtractor();
extractor.setConfig(mConfig);
- when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
- NotificationManager.IMPORTANCE_MIN);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
@@ -101,8 +99,6 @@
ImportanceExtractor extractor = new ImportanceExtractor();
extractor.setConfig(mConfig);
- when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
- NotificationManager.IMPORTANCE_MIN);
NotificationChannel channel =
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_HIGH);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
index f609306..6f7bace 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelLoggerFake.java
@@ -28,6 +28,13 @@
CallRecord(NotificationChannelEvent event) {
this.event = event;
}
+
+ @Override
+ public String toString() {
+ return "CallRecord{" +
+ "event=" + event +
+ '}';
+ }
}
private List<CallRecord> mCalls = new ArrayList<>();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 348e015..267a506 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -52,6 +52,7 @@
import static android.app.PendingIntent.FLAG_MUTABLE;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -187,6 +188,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.Pair;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
@@ -198,6 +200,7 @@
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.InstanceIdSequenceFake;
+import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
@@ -219,6 +222,7 @@
import com.google.common.collect.ImmutableList;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -271,6 +275,7 @@
private WindowManagerInternal mWindowManagerInternal;
@Mock
private PermissionHelper mPermissionHelper;
+ private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
private TestableContext mContext = spy(getContext());
private final String PKG = mContext.getPackageName();
private TestableLooper mTestableLooper;
@@ -303,6 +308,8 @@
ActivityManagerInternal mAmi;
@Mock
private Looper mMainLooper;
+ @Mock
+ private NotificationManager mMockNm;
@Mock
IIntentSender pi1;
@@ -381,9 +388,6 @@
"android.permission.WRITE_DEVICE_CONFIG",
"android.permission.READ_DEVICE_CONFIG",
"android.permission.READ_CONTACTS");
- Settings.Secure.putIntForUser(
- getContext().getContentResolver(),
- Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM);
MockitoAnnotations.initMocks(this);
@@ -405,6 +409,7 @@
LocalServices.removeServiceForTest(PermissionPolicyInternal.class);
LocalServices.addService(PermissionPolicyInternal.class, mPermissionPolicyInternal);
mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
+ mContext.addMockSystemService(NotificationManager.class, mMockNm);
doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
@@ -444,6 +449,8 @@
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(true);
+
ActivityManager.AppTask task = mock(ActivityManager.AppTask.class);
List<ActivityManager.AppTask> taskList = new ArrayList<>();
ActivityManager.RecentTaskInfo taskInfo = new ActivityManager.RecentTaskInfo();
@@ -502,7 +509,7 @@
mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager,
mock(TelephonyManager.class),
mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class),
- mTelecomManager);
+ mTelecomManager, mLogger);
// Return first true for RoleObserver main-thread check
when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
@@ -578,6 +585,7 @@
assertNotNull(mBinderService.getNotificationChannel(
PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID));
clearInvocations(mRankingHandler);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
}
@After
@@ -1230,8 +1238,7 @@
@Test
public void testEnqueuedBlockedNotifications_blockedApp() throws Exception {
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
-
- mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
mBinderService.enqueueNotificationWithTag(PKG, PKG,
@@ -1244,8 +1251,7 @@
@Test
public void testEnqueuedBlockedNotifications_blockedAppForegroundService() throws Exception {
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
-
- mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -1338,6 +1344,30 @@
}
@Test
+ public void testSetNotificationsEnabledForPackage_noChange() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+ mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, true);
+
+ verify(mPermissionHelper, never()).setNotificationPermission(
+ anyString(), anyInt(), anyBoolean(), anyBoolean());
+ }
+
+ @Test
+ public void testSetNotificationsEnabledForPackage() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+ mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false);
+
+ verify(mPermissionHelper).setNotificationPermission(
+ mContext.getPackageName(), UserHandle.getUserId(mUid), false, true);
+
+ verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt());
+ List<NotificationChannelLoggerFake.CallRecord> calls = mLogger.getCalls();
+ Assert.assertEquals(
+ NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED,
+ calls.get(calls.size() -1).event);
+ }
+
+ @Test
public void testBlockedNotifications_blockedByAssistant() throws Exception {
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
@@ -1364,7 +1394,6 @@
@Test
public void testBlockedNotifications_blockedByUser() throws Exception {
- mService.setPreferencesHelper(mPreferencesHelper);
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
@@ -1373,7 +1402,7 @@
NotificationRecord r = generateNotificationRecord(channel);
mService.addEnqueuedNotification(r);
- when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE);
+ when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
@@ -1386,8 +1415,32 @@
}
@Test
+ public void testEnqueueNotificationInternal_noChannel() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
+ NotificationRecord nr = generateNotificationRecord(
+ new NotificationChannel("did not create", "", IMPORTANCE_DEFAULT));
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+ nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+ waitForIdle();
+
+ verify(mPermissionHelper).hasPermission(mUid);
+ verify(mPermissionHelper, never()).hasPermission(Process.SYSTEM_UID);
+
+ reset(mPermissionHelper);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+ nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+ waitForIdle();
+
+ verify(mPermissionHelper).hasPermission(mUid);
+ assertThat(mService.mChannelToastsSent).contains(mUid);
+ }
+
+ @Test
public void testEnqueueNotification_appBlocked() throws Exception {
- mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
mBinderService.enqueueNotificationWithTag(PKG, PKG,
"testEnqueueNotification_appBlocked", 0,
@@ -2682,6 +2735,49 @@
}
@Test
+ public void testDefaultChannelUpdatesApp_postMigrationToPermissions() throws Exception {
+ final NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
+ PKG_N_MR1, ActivityManager.getCurrentUser(), PKG_N_MR1,
+ NotificationChannel.DEFAULT_CHANNEL_ID);
+ defaultChannel.setImportance(IMPORTANCE_NONE);
+
+ mBinderService.updateNotificationChannelForPackage(PKG_N_MR1, mUid, defaultChannel);
+
+ verify(mPermissionHelper).setNotificationPermission(
+ PKG_N_MR1, ActivityManager.getCurrentUser(), false, true);
+ }
+
+ @Test
+ public void testPostNotification_appPermissionFixed() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+ when(mPermissionHelper.isPermissionFixed(PKG, 0)).thenReturn(true);
+
+ NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testPostNotification_appPermissionFixed", 0,
+ temp.getNotification(), 0);
+ waitForIdle();
+ assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+ StatusBarNotification[] notifs =
+ mBinderService.getActiveNotifications(PKG);
+ assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue();
+ }
+
+ @Test
+ public void testSummaryNotification_appPermissionFixed() {
+ NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
+ mService.addNotification(temp);
+
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+ when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true);
+
+ NotificationRecord r = mService.createAutoGroupSummary(
+ temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey(), false);
+
+ assertThat(r.isImportanceFixed()).isTrue();
+ }
+
+ @Test
public void testTvExtenderChannelOverride_onTv() throws Exception {
mService.setIsTelevision(true);
mService.setPreferencesHelper(mPreferencesHelper);
@@ -2714,13 +2810,12 @@
@Test
public void testUpdateAppNotifyCreatorBlock() throws Exception {
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_DEFAULT);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- // should trigger a broadcast
mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
Thread.sleep(500);
waitForIdle();
+
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
@@ -2732,7 +2827,7 @@
@Test
public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception {
- mService.setPreferencesHelper(mPreferencesHelper);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
@@ -2740,15 +2835,12 @@
@Test
public void testUpdateAppNotifyCreatorUnblock() throws Exception {
- mService.setPreferencesHelper(mPreferencesHelper);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
- // should not trigger a broadcast
- when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED);
-
- // should trigger a broadcast
- mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
+ mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true);
Thread.sleep(500);
waitForIdle();
+
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
@@ -4340,7 +4432,7 @@
assertEquals(IMPORTANCE_LOW,
mService.getNotificationRecord(sbn.getKey()).getImportance());
- assertEquals(IMPORTANCE_UNSPECIFIED, mBinderService.getPackageImportance(
+ assertEquals(IMPORTANCE_DEFAULT, mBinderService.getPackageImportance(
sbn.getPackageName()));
nb = new Notification.Builder(mContext)
@@ -4856,6 +4948,7 @@
@Test
public void testBackup() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
int systemChecks = mService.countSystemChecks;
when(mListeners.queryPackageForServices(anyString(), anyInt(), anyInt()))
.thenReturn(new ArraySet<>());
@@ -5959,8 +6052,7 @@
.thenReturn(false);
// notifications from this package are blocked by the user
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
setAppInForegroundForToasts(mUid, true);
@@ -6256,8 +6348,7 @@
.thenReturn(false);
// notifications from this package are blocked by the user
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
setAppInForegroundForToasts(mUid, false);
@@ -6343,8 +6434,7 @@
.thenReturn(true);
// notifications from this package are NOT blocked by the user
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_LOW);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
// enqueue toast -> no toasts enqueued
((INotificationManager) mService.mService).enqueueToast(testPackage, new Binder(),
@@ -6365,8 +6455,7 @@
.thenReturn(false);
// notifications from this package are blocked by the user
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
setAppInForegroundForToasts(mUid, false);
@@ -6389,8 +6478,7 @@
.thenReturn(true);
// notifications from this package ARE blocked by the user
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
setAppInForegroundForToasts(mUid, false);
@@ -7299,6 +7387,14 @@
}
@Test
+ public void testAreNotificationsEnabledForPackage() throws Exception {
+ mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
+ mUid);
+
+ verify(mPermissionHelper).hasPermission(mUid);
+ }
+
+ @Test
public void testAreNotificationsEnabledForPackage_crossUser() throws Exception {
try {
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
@@ -7307,21 +7403,31 @@
} catch (SecurityException e) {
// pass
}
+ verify(mPermissionHelper, never()).hasPermission(anyInt());
// cross user, with permission, no problem
enableInteractAcrossUsers();
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
mUid + UserHandle.PER_USER_RANGE);
- verify(mPermissionHelper, never()).hasPermission(anyInt());
+ verify(mPermissionHelper).hasPermission(mUid + UserHandle.PER_USER_RANGE);
}
@Test
- public void testAreNotificationsEnabledForPackage_viaInternalService() throws Exception {
- assertEquals(mInternalService.areNotificationsEnabledForPackage(
- mContext.getPackageName(), mUid),
- mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid));
- verify(mPermissionHelper, never()).hasPermission(anyInt());
+ public void testAreNotificationsEnabledForPackage_viaInternalService() {
+ mInternalService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid);
+ verify(mPermissionHelper).hasPermission(mUid);
+ }
+
+ @Test
+ public void testGetPackageImportance() throws Exception {
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
+ assertThat(mBinderService.getPackageImportance(mContext.getPackageName()))
+ .isEqualTo(IMPORTANCE_DEFAULT);
+
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
+ assertThat(mBinderService.getPackageImportance(mContext.getPackageName()))
+ .isEqualTo(IMPORTANCE_NONE);
}
@Test
@@ -7516,46 +7622,53 @@
}
@Test
- public void testOnBubbleNotificationSuppressionChanged() throws Exception {
+ public void testOnBubbleMetadataFlagChanged() throws Exception {
setUpPrefsForBubbles(PKG, mUid,
true /* global */,
BUBBLE_PREFERENCE_ALL /* app */,
true /* channel */);
- // Bubble notification
+ // Post a bubble notification
NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag");
-
+ // Set this so that the bubble can be suppressed
+ nr.getNotification().getBubbleMetadata().setFlags(
+ Notification.BubbleMetadata.FLAG_SUPPRESSABLE_BUBBLE);
mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
- // NOT suppressed
+ // Check the flags
Notification n = mBinderService.getActiveNotifications(PKG)[0].getNotification();
assertFalse(n.getBubbleMetadata().isNotificationSuppressed());
+ assertFalse(n.getBubbleMetadata().getAutoExpandBubble());
+ assertFalse(n.getBubbleMetadata().isBubbleSuppressed());
+ assertTrue(n.getBubbleMetadata().isBubbleSuppressable());
// Reset as this is called when the notif is first sent
reset(mListeners);
- // Test: update suppression to true
- mService.mNotificationDelegate.onBubbleNotificationSuppressionChanged(nr.getKey(), true,
- false);
+ // Test: change the flags
+ int flags = Notification.BubbleMetadata.FLAG_SUPPRESSABLE_BUBBLE;
+ flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE;
+ flags |= Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
+ flags |= Notification.BubbleMetadata.FLAG_SUPPRESS_BUBBLE;
+ mService.mNotificationDelegate.onBubbleMetadataFlagChanged(nr.getKey(), flags);
waitForIdle();
// Check
n = mBinderService.getActiveNotifications(PKG)[0].getNotification();
- assertTrue(n.getBubbleMetadata().isNotificationSuppressed());
+ assertEquals(flags, n.getBubbleMetadata().getFlags());
// Reset to check again
reset(mListeners);
- // Test: update suppression to false
- mService.mNotificationDelegate.onBubbleNotificationSuppressionChanged(nr.getKey(), false,
- false);
+ // Test: clear flags
+ mService.mNotificationDelegate.onBubbleMetadataFlagChanged(nr.getKey(), 0);
waitForIdle();
// Check
n = mBinderService.getActiveNotifications(PKG)[0].getNotification();
- assertFalse(n.getBubbleMetadata().isNotificationSuppressed());
+ assertEquals(0, n.getBubbleMetadata().getFlags());
}
@Test
@@ -8964,48 +9077,13 @@
}
@Test
- public void testMigrationDisabledByDefault() {
- assertThat(mService.mEnableAppSettingMigration).isFalse();
- }
-
- @Test
- public void testPostNotification_channelLockedFixed() throws Exception {
- mTestNotificationChannel.setImportanceLockedByOEM(true);
-
- NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG,
- "testPostNotification_appPermissionFixed", 0,
- temp.getNotification(), 0);
- waitForIdle();
- assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
- StatusBarNotification[] notifs =
- mBinderService.getActiveNotifications(PKG);
- assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue();
-
- mBinderService.cancelAllNotifications(PKG, 0);
- waitForIdle();
-
- mTestNotificationChannel.setImportanceLockedByOEM(false);
- mTestNotificationChannel.setImportanceLockedByCriticalDeviceFunction(true);
-
- temp = generateNotificationRecord(mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG,
- "testPostNotification_appPermissionFixed", 0,
- temp.getNotification(), 0);
- waitForIdle();
- assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
- notifs = mBinderService.getActiveNotifications(PKG);
- assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue();
- }
-
- @Test
public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException {
mService.setPreferencesHelper(mPreferencesHelper);
- when(mPreferencesHelper.getImportance(PKG, mUid)).thenReturn(IMPORTANCE_NONE);
+
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList())
.isEmpty();
- verify(mPermissionHelper, never()).hasPermission(anyInt());
verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
}
@@ -9099,8 +9177,7 @@
nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.setNotificationsEnabledForPackage(
- r.getSbn().getPackageName(), r.getUid(), false);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
// normal blocked notifications - blocked
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
@@ -9138,6 +9215,67 @@
}
@Test
+ public void testMediaNotificationsBypassBlock_atPost() throws Exception {
+ when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+
+ Notification.Builder nb = new Notification.Builder(
+ mContext, mTestNotificationChannel.getId())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .addAction(new Notification.Action.Builder(null, "test", null).build());
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
+
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // just using the style - blocked
+ mService.clearNotifications();
+ reset(mUsageStats);
+ nb.setStyle(new Notification.MediaStyle());
+ sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mService.addEnqueuedNotification(r);
+ runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // style + media session - bypasses block
+ mService.clearNotifications();
+ reset(mUsageStats);
+ nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
+ sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mService.addEnqueuedNotification(r);
+ runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats, never()).registerBlocked(any());
+ verify(mUsageStats).registerPostedByApp(any());
+ }
+
+ @Test
public void testCallNotificationsBypassBlock() throws Exception {
when(mAmi.getPendingIntentFlags(any(IIntentSender.class)))
.thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT);
@@ -9152,8 +9290,7 @@
nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.setNotificationsEnabledForPackage(
- r.getSbn().getPackageName(), r.getUid(), false);
+ when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
// normal blocked notifications - blocked
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
@@ -9183,12 +9320,152 @@
r.getSbn().getPackageName(), r.getUser())).thenReturn(true);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+
+ // set telecom manager to null - blocked
+ mService.setTelecomManager(null);
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false))
+ .isFalse();
+
+ // set telecom feature to false - blocked
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false);
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false))
+ .isFalse();
}
@Test
- public void testGetAllUsersNotificationPermissions_migrationNotEnabled() {
- // make sure we don't bother if the migration is not enabled
- assertThat(mService.getAllUsersNotificationPermissions()).isNull();
+ public void testCallNotificationsBypassBlock_atPost() throws Exception {
+ when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+
+ Notification.Builder nb =
+ new Notification.Builder(mContext, mTestNotificationChannel.getId())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .addAction(new Notification.Action.Builder(null, "test", null).build());
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mBinderService.setNotificationsEnabledForPackage(
+ r.getSbn().getPackageName(), r.getUid(), false);
+
+ // normal blocked notifications - blocked
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // just using the style - blocked
+ mService.clearNotifications();
+ reset(mUsageStats);
+ Person person = new Person.Builder().setName("caller").build();
+ nb.setStyle(Notification.CallStyle.forOngoingCall(person, mock(PendingIntent.class)));
+ nb.setFullScreenIntent(mock(PendingIntent.class), true);
+ sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, nb.build(),
+ UserHandle.getUserHandleForUid(mUid), null, 0);
+ r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mService.addEnqueuedNotification(r);
+ runnable = mService.new PostNotificationRunnable(
+ r.getKey(), r.getSbn().getPackageName(), r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // style + managed call - bypasses block
+ mService.clearNotifications();
+ reset(mUsageStats);
+ when(mTelecomManager.isInManagedCall()).thenReturn(true);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats, never()).registerBlocked(any());
+ verify(mUsageStats).registerPostedByApp(any());
+
+ // style + self managed call - bypasses block
+ mService.clearNotifications();
+ reset(mUsageStats);
+ when(mTelecomManager.isInSelfManagedCall(r.getSbn().getPackageName(), r.getUser()))
+ .thenReturn(true);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats, never()).registerBlocked(any());
+ verify(mUsageStats).registerPostedByApp(any());
+
+ // set telecom manager to null - notifications should be blocked
+ // but post notifications runnable should not crash
+ mService.clearNotifications();
+ reset(mUsageStats);
+ mService.setTelecomManager(null);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // set FEATURE_TELECOM to false - notifications should be blocked
+ // but post notifications runnable should not crash
+ mService.setTelecomManager(mTelecomManager);
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false);
+ reset(mUsageStats);
+ mService.setTelecomManager(null);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+ }
+
+ @Test
+ public void testGetAllUsersNotificationPermissions() {
+ // In this case, there are multiple users each with notification permissions (and also,
+ // for good measure, some without).
+ // make sure the collection returned contains info for all of them
+ final List<UserInfo> userInfos = new ArrayList<>();
+ userInfos.add(new UserInfo(0, "user0", 0));
+ userInfos.add(new UserInfo(1, "user1", 0));
+ userInfos.add(new UserInfo(2, "user2", 0));
+ when(mUm.getUsers()).thenReturn(userInfos);
+
+ // construct the permissions for each of them
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(),
+ permissions1 = new ArrayMap<>();
+ permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false));
+ permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true));
+ permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false));
+ permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true));
+ when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0);
+ when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1);
+ when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>());
+
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions =
+ mService.getAllUsersNotificationPermissions();
+ assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first);
+ assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second);
+ assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first);
+ assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second);
+ assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first);
+ assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second);
+ assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first);
+ assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second);
}
@Test
@@ -9294,4 +9571,77 @@
// the notifyPostedLocked function is called twice.
verify(mListeners, times(2)).notifyPostedLocked(any(), any());
}
+
+ @Test
+ public void testMaybeShowReviewPermissionsNotification_unknown() {
+ // Set up various possible states of the settings int and confirm whether or not the
+ // notification is shown as expected
+
+ // Initial state: default/unknown setting, make sure nothing happens
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN);
+ mService.maybeShowInitialReviewPermissionsNotification();
+ verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class));
+ }
+
+ @Test
+ public void testMaybeShowReviewPermissionsNotification_shouldShow() {
+ // If state is SHOULD_SHOW, it ... should show
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
+ mService.maybeShowInitialReviewPermissionsNotification();
+ verify(mMockNm, times(1)).notify(eq(NotificationManagerService.TAG),
+ eq(SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS),
+ any(Notification.class));
+ }
+
+ @Test
+ public void testMaybeShowReviewPermissionsNotification_alreadyShown() {
+ // If state is either USER_INTERACTED or DISMISSED, we should not show this on boot
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED);
+ mService.maybeShowInitialReviewPermissionsNotification();
+
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_DISMISSED);
+ mService.maybeShowInitialReviewPermissionsNotification();
+
+ verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class));
+ }
+
+ @Test
+ public void testMaybeShowReviewPermissionsNotification_reshown() {
+ // If we have re-shown the notification and the user did not subsequently interacted with
+ // it, then make sure we show when trying on boot
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
+ mService.maybeShowInitialReviewPermissionsNotification();
+ verify(mMockNm, times(1)).notify(eq(NotificationManagerService.TAG),
+ eq(SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS),
+ any(Notification.class));
+ }
+
+ @Test
+ public void testRescheduledReviewPermissionsNotification() {
+ // when rescheduled, the notification goes through the NotificationManagerInternal service
+ // this call doesn't need to know anything about previously scheduled state -- if called,
+ // it should send the notification & write the appropriate int to Settings
+ mInternalService.sendReviewPermissionsNotification();
+
+ // Notification should be sent
+ verify(mMockNm, times(1)).notify(eq(NotificationManagerService.TAG),
+ eq(SystemMessageProto.SystemMessage.NOTE_REVIEW_NOTIFICATION_PERMISSIONS),
+ any(Notification.class));
+
+ // write STATE_RESHOWN to settings
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
deleted file mode 100755
index b751c7f..0000000
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ /dev/null
@@ -1,877 +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.notification;
-
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_IGNORED;
-import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-import static android.app.PendingIntent.FLAG_MUTABLE;
-import static android.app.PendingIntent.FLAG_ONE_SHOT;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.UserHandle.USER_SYSTEM;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.app.IActivityManager;
-import android.app.INotificationManager;
-import android.app.IUriGrantsManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.StatsManager;
-import android.app.admin.DevicePolicyManagerInternal;
-import android.app.usage.UsageStatsManagerInternal;
-import android.companion.ICompanionDeviceManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.IIntentSender;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.LauncherApps;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutServiceInternal;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.media.AudioManager;
-import android.media.session.MediaSession;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.service.notification.NotificationListenerFilter;
-import android.service.notification.StatusBarNotification;
-import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableContext;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.testing.TestablePermissions;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.AtomicFile;
-import android.util.Pair;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.app.IAppOpsService;
-import com.android.internal.logging.InstanceIdSequence;
-import com.android.internal.logging.InstanceIdSequenceFake;
-import com.android.server.DeviceIdleInternal;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.UiServiceTestCase;
-import com.android.server.lights.LightsManager;
-import com.android.server.lights.LogicalLight;
-import com.android.server.notification.NotificationManagerService.NotificationAssistants;
-import com.android.server.notification.NotificationManagerService.NotificationListeners;
-import com.android.server.statusbar.StatusBarManagerInternal;
-import com.android.server.uri.UriGrantsManagerInternal;
-import com.android.server.utils.quota.MultiRateLimiter;
-import com.android.server.wm.ActivityTaskManagerInternal;
-import com.android.server.wm.WindowManagerInternal;
-
-import org.junit.After;
-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;
-import org.mockito.stubbing.Answer;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-/**
- * Tests that NMS reads/writes the app notification state from Package/PermissionManager when
- * migration is enabled. Because the migration field is read onStart
- * TODO (b/194833441): migrate these tests to NotificationManagerServiceTest when the migration is
- * permanently enabled.
- */
-public class NotificationPermissionMigrationTest extends UiServiceTestCase {
- private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
- private static final int UID_HEADLESS = 1000000;
-
- private final int mUid = Binder.getCallingUid();
- private TestableNotificationManagerService mService;
- private INotificationManager mBinderService;
- private NotificationManagerInternal mInternalService;
- private ShortcutHelper mShortcutHelper;
- @Mock
- private IPackageManager mPackageManager;
- @Mock
- private PackageManager mPackageManagerClient;
- @Mock
- private PackageManagerInternal mPackageManagerInternal;
- @Mock
- private WindowManagerInternal mWindowManagerInternal;
- @Mock
- private PermissionHelper mPermissionHelper;
- private TestableContext mContext = spy(getContext());
- private final String PKG = mContext.getPackageName();
- private TestableLooper mTestableLooper;
- @Mock
- private RankingHelper mRankingHelper;
- @Mock private PreferencesHelper mPreferencesHelper;
- AtomicFile mPolicyFile;
- File mFile;
- @Mock
- private NotificationUsageStats mUsageStats;
- @Mock
- private UsageStatsManagerInternal mAppUsageStats;
- @Mock
- private AudioManager mAudioManager;
- @Mock
- private LauncherApps mLauncherApps;
- @Mock
- private ShortcutServiceInternal mShortcutServiceInternal;
- @Mock
- private UserManager mUserManager;
- @Mock
- ActivityManager mActivityManager;
- @Mock
- Resources mResources;
- @Mock
- RankingHandler mRankingHandler;
- @Mock
- ActivityManagerInternal mAmi;
- @Mock
- private Looper mMainLooper;
-
- @Mock
- IIntentSender pi1;
-
- private static final int MAX_POST_DELAY = 1000;
-
- private NotificationChannel mTestNotificationChannel = new NotificationChannel(
- TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
-
- private static final String VALID_CONVO_SHORTCUT_ID = "shortcut";
-
- @Mock
- private NotificationListeners mListeners;
- @Mock
- private NotificationListenerFilter mNlf;
- @Mock private NotificationAssistants mAssistants;
- @Mock private ConditionProviders mConditionProviders;
- private ManagedServices.ManagedServiceInfo mListener;
- @Mock private ICompanionDeviceManager mCompanionMgr;
- @Mock SnoozeHelper mSnoozeHelper;
- @Mock GroupHelper mGroupHelper;
- @Mock
- IBinder mPermOwner;
- @Mock
- IActivityManager mAm;
- @Mock
- ActivityTaskManagerInternal mAtm;
- @Mock
- IUriGrantsManager mUgm;
- @Mock
- UriGrantsManagerInternal mUgmInternal;
- @Mock
- AppOpsManager mAppOpsManager;
- @Mock
- private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback
- mNotificationAssistantAccessGrantedCallback;
- @Mock
- UserManager mUm;
- @Mock
- NotificationHistoryManager mHistoryManager;
- @Mock
- StatsManager mStatsManager;
- @Mock
- AlarmManager mAlarmManager;
- @Mock
- MultiRateLimiter mToastRateLimiter;
- BroadcastReceiver mPackageIntentReceiver;
- NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
- private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
- 1 << 30);
- @Mock
- StatusBarManagerInternal mStatusBar;
-
- private NotificationManagerService.WorkerHandler mWorkerHandler;
-
- @Before
- public void setUp() throws Exception {
- // These should be the only difference in setup from NMSTest
- Settings.Secure.putIntForUser(
- getContext().getContentResolver(),
- Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM);
- Settings.Global.putInt(getContext().getContentResolver(),
- Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 1);
-
- // Shell permissions will override permissions of our app, so add all necessary permissions
- // for this test here:
- InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
- "android.permission.WRITE_DEVICE_CONFIG",
- "android.permission.READ_DEVICE_CONFIG",
- "android.permission.READ_CONTACTS");
-
- MockitoAnnotations.initMocks(this);
-
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
-
- DeviceIdleInternal deviceIdleInternal = mock(DeviceIdleInternal.class);
- when(deviceIdleInternal.getNotificationAllowlistDuration()).thenReturn(3000L);
-
- LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
- LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
- LocalServices.removeServiceForTest(WindowManagerInternal.class);
- LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
- LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
- LocalServices.addService(StatusBarManagerInternal.class, mStatusBar);
- LocalServices.removeServiceForTest(DeviceIdleInternal.class);
- LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal);
- LocalServices.removeServiceForTest(ActivityManagerInternal.class);
- LocalServices.addService(ActivityManagerInternal.class, mAmi);
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
- LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
- mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
- when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
-
- doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
-
- mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
- mNotificationInstanceIdSequence);
-
- // Use this testable looper.
- mTestableLooper = TestableLooper.get(this);
- // MockPackageManager - default returns ApplicationInfo with matching calling UID
- mContext.setMockPackageManager(mPackageManagerClient);
-
- when(mPackageManager.getApplicationInfo(anyString(), anyLong(), anyInt()))
- .thenAnswer((Answer<ApplicationInfo>) invocation -> {
- Object[] args = invocation.getArguments();
- return getApplicationInfo((String) args[0], mUid);
- });
- when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
- .thenAnswer((Answer<ApplicationInfo>) invocation -> {
- Object[] args = invocation.getArguments();
- return getApplicationInfo((String) args[0], mUid);
- });
- when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
- when(mPackageManagerInternal.isSameApp(anyString(), anyInt(), anyInt())).thenAnswer(
- (Answer<Boolean>) invocation -> {
- Object[] args = invocation.getArguments();
- return (int) args[1] == mUid;
- });
- final LightsManager mockLightsManager = mock(LightsManager.class);
- when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
- when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
- when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
- when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
- when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
- when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
- mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
-
- // write to a test file; the system file isn't readable from tests
- mFile = new File(mContext.getCacheDir(), "test.xml");
- mFile.createNewFile();
- final String preupgradeXml = "<notification-policy></notification-policy>";
- mPolicyFile = new AtomicFile(mFile);
- FileOutputStream fos = mPolicyFile.startWrite();
- fos.write(preupgradeXml.getBytes());
- mPolicyFile.finishWrite(fos);
-
- // Setup managed services
- when(mNlf.isTypeAllowed(anyInt())).thenReturn(true);
- when(mNlf.isPackageAllowed(any())).thenReturn(true);
- when(mNlf.isPackageAllowed(null)).thenReturn(true);
- when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf);
- mListener = mListeners.new ManagedServiceInfo(
- null, new ComponentName(PKG, "test_class"),
- UserHandle.getUserId(mUid), true, null, 0, 123);
- ComponentName defaultComponent = ComponentName.unflattenFromString("config/device");
- ArraySet<ComponentName> components = new ArraySet<>();
- components.add(defaultComponent);
- when(mListeners.getDefaultComponents()).thenReturn(components);
- when(mConditionProviders.getDefaultPackages())
- .thenReturn(new ArraySet<>(Arrays.asList("config")));
- when(mAssistants.getDefaultComponents()).thenReturn(components);
- when(mAssistants.queryPackageForServices(
- anyString(), anyInt(), anyInt())).thenReturn(components);
- when(mListeners.checkServiceTokenLocked(null)).thenReturn(mListener);
- ManagedServices.Config listenerConfig = new ManagedServices.Config();
- listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
- when(mListeners.getConfig()).thenReturn(listenerConfig);
- ManagedServices.Config assistantConfig = new ManagedServices.Config();
- assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
- when(mAssistants.getConfig()).thenReturn(assistantConfig);
- ManagedServices.Config dndConfig = new ManagedServices.Config();
- dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
- when(mConditionProviders.getConfig()).thenReturn(dndConfig);
-
- when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
-
- // apps allowed as convos
- mService.setStringArrayResourceValue(PKG_O);
-
- mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper()));
- mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient,
- mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
- mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
- mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
- mAppOpsManager, mock(IAppOpsService.class), mUm, mHistoryManager, mStatsManager,
- mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper,
- mock(UsageStatsManagerInternal.class), mock(TelecomManager.class));
- // Return first true for RoleObserver main-thread check
- when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
- mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
-
- mService.setAudioManager(mAudioManager);
-
- mShortcutHelper = mService.getShortcutHelper();
- mShortcutHelper.setLauncherApps(mLauncherApps);
- mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);
- mShortcutHelper.setUserManager(mUserManager);
-
- // Capture PackageIntentReceiver
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
- ArgumentCaptor<IntentFilter> intentFilterCaptor =
- ArgumentCaptor.forClass(IntentFilter.class);
-
- verify(mContext, atLeastOnce()).registerReceiverAsUser(broadcastReceiverCaptor.capture(),
- any(), intentFilterCaptor.capture(), any(), any());
- verify(mContext, atLeastOnce()).registerReceiver(broadcastReceiverCaptor.capture(),
- intentFilterCaptor.capture());
- List<BroadcastReceiver> broadcastReceivers = broadcastReceiverCaptor.getAllValues();
- List<IntentFilter> intentFilters = intentFilterCaptor.getAllValues();
-
- for (int i = 0; i < intentFilters.size(); i++) {
- final IntentFilter filter = intentFilters.get(i);
- if (filter.hasAction(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED)
- && filter.hasAction(Intent.ACTION_PACKAGES_UNSUSPENDED)
- && filter.hasAction(Intent.ACTION_PACKAGES_SUSPENDED)) {
- mPackageIntentReceiver = broadcastReceivers.get(i);
- }
- }
- assertNotNull("package intent receiver should exist", mPackageIntentReceiver);
-
- // Pretend the shortcut exists
- List<ShortcutInfo> shortcutInfos = new ArrayList<>();
- ShortcutInfo info = mock(ShortcutInfo.class);
- when(info.getPackage()).thenReturn(PKG);
- when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
- when(info.getUserId()).thenReturn(USER_SYSTEM);
- when(info.isLongLived()).thenReturn(true);
- when(info.isEnabled()).thenReturn(true);
- shortcutInfos.add(info);
- when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
- when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
- anyString(), anyInt(), any())).thenReturn(true);
- when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
-
- // Set the testable bubble extractor
- RankingHelper rankingHelper = mService.getRankingHelper();
- BubbleExtractor extractor = rankingHelper.findExtractor(BubbleExtractor.class);
- extractor.setActivityManager(mActivityManager);
-
- // Tests call directly into the Binder.
- mBinderService = mService.getBinderService();
- mInternalService = mService.getInternalService();
-
- mBinderService.createNotificationChannels(
- PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
- mBinderService.createNotificationChannels(
- PKG_P, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
- mBinderService.createNotificationChannels(
- PKG_O, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
- assertNotNull(mBinderService.getNotificationChannel(
- PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID));
- clearInvocations(mRankingHandler);
- }
-
- @After
- public void tearDown() throws Exception {
- if (mFile != null) mFile.delete();
-
- try {
- mService.onDestroy();
- } catch (IllegalStateException | IllegalArgumentException e) {
- // can throw if a broadcast receiver was never registered
- }
-
- InstrumentationRegistry.getInstrumentation()
- .getUiAutomation().dropShellPermissionIdentity();
- // Remove scheduled messages that would be processed when the test is already done, and
- // could cause issues, for example, messages that remove/cancel shown toasts (this causes
- // problematic interactions with mocks when they're no longer working as expected).
- mWorkerHandler.removeCallbacksAndMessages(null);
- }
-
- private ApplicationInfo getApplicationInfo(String pkg, int uid) {
- final ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.uid = uid;
- switch (pkg) {
- case PKG_N_MR1:
- applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
- break;
- case PKG_O:
- applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
- break;
- case PKG_P:
- applicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
- break;
- default:
- applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
- break;
- }
- return applicationInfo;
- }
-
- public void waitForIdle() {
- mTestableLooper.processAllMessages();
- }
-
- private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
- return generateNotificationRecord(channel, null);
- }
-
- private NotificationRecord generateNotificationRecord(NotificationChannel channel,
- Notification.TvExtender extender) {
- if (channel == null) {
- channel = mTestNotificationChannel;
- }
- Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
- .setContentTitle("foo")
- .setSmallIcon(android.R.drawable.sym_def_app_icon)
- .addAction(new Notification.Action.Builder(null, "test", null).build());
- if (extender != null) {
- nb.extend(extender);
- }
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- return new NotificationRecord(mContext, sbn, channel);
- }
-
- private void enableInteractAcrossUsers() {
- TestablePermissions perms = mContext.getTestablePermissions();
- perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
- }
-
- @Test
- public void testAreNotificationsEnabledForPackage() throws Exception {
- mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
- mUid);
-
- verify(mPermissionHelper).hasPermission(mUid);
- }
-
- @Test
- public void testAreNotificationsEnabledForPackage_crossUser() throws Exception {
- try {
- mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
- mUid + UserHandle.PER_USER_RANGE);
- fail("Cannot call cross user without permission");
- } catch (SecurityException e) {
- // pass
- }
- verify(mPermissionHelper, never()).hasPermission(anyInt());
-
- // cross user, with permission, no problem
- enableInteractAcrossUsers();
- mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
- mUid + UserHandle.PER_USER_RANGE);
-
- verify(mPermissionHelper).hasPermission(mUid + UserHandle.PER_USER_RANGE);
- }
-
- @Test
- public void testAreNotificationsEnabledForPackage_viaInternalService() {
- mInternalService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid);
- verify(mPermissionHelper).hasPermission(mUid);
- }
-
- @Test
- public void testGetPackageImportance() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- assertThat(mBinderService.getPackageImportance(mContext.getPackageName()))
- .isEqualTo(IMPORTANCE_DEFAULT);
-
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
- assertThat(mBinderService.getPackageImportance(mContext.getPackageName()))
- .isEqualTo(IMPORTANCE_NONE);
- }
-
- @Test
- public void testEnqueueNotificationInternal_noChannel() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
- NotificationRecord nr = generateNotificationRecord(
- new NotificationChannel("did not create", "", IMPORTANCE_DEFAULT));
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
-
- verify(mPermissionHelper).hasPermission(mUid);
- verify(mPermissionHelper, never()).hasPermission(Process.SYSTEM_UID);
-
- reset(mPermissionHelper);
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
-
- verify(mPermissionHelper).hasPermission(mUid);
- assertThat(mService.mChannelToastsSent).contains(mUid);
- }
-
- @Test
- public void testSetNotificationsEnabledForPackage_noChange() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, true);
-
- verify(mPermissionHelper, never()).setNotificationPermission(
- anyString(), anyInt(), anyBoolean(), anyBoolean());
- }
-
- @Test
- public void testSetNotificationsEnabledForPackage() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false);
-
- verify(mPermissionHelper).setNotificationPermission(
- mContext.getPackageName(), UserHandle.getUserId(mUid), false, true);
-
- verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt());
- }
-
- @Test
- public void testUpdateAppNotifyCreatorBlock() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
-
- mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
- Thread.sleep(500);
- waitForIdle();
-
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
-
- assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
- captor.getValue().getAction());
- assertEquals(PKG, captor.getValue().getPackage());
- assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
- }
-
- @Test
- public void testUpdateAppNotifyCreatorUnblock() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
-
- mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true);
- Thread.sleep(500);
- waitForIdle();
-
- ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
-
- assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
- captor.getValue().getAction());
- assertEquals(PKG, captor.getValue().getPackage());
- assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
- }
-
- @Test
- public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException {
- mService.setPreferencesHelper(mPreferencesHelper);
-
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
-
- assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList())
- .isEmpty();
- verify(mPreferencesHelper, never()).getImportance(anyString(), anyInt());
- verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
- }
-
- @Test
- public void testBlockedNotifications_blockedByUser() throws Exception {
- when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
- when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
-
- NotificationChannel channel = new NotificationChannel("id", "name",
- NotificationManager.IMPORTANCE_HIGH);
- NotificationRecord r = generateNotificationRecord(channel);
- mService.addEnqueuedNotification(r);
-
- when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
-
- NotificationManagerService.PostNotificationRunnable runnable =
- mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
- waitForIdle();
-
- verify(mUsageStats).registerBlocked(any());
- verify(mUsageStats, never()).registerPostedByApp(any());
- }
-
- @Test
- public void testEnqueueNotification_appBlocked() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG,
- "testEnqueueNotification_appBlocked", 0,
- generateNotificationRecord(null).getNotification(), 0);
- waitForIdle();
- verify(mWorkerHandler, never()).post(
- any(NotificationManagerService.EnqueueNotificationRunnable.class));
- }
-
- @Test
- public void testDefaultChannelDoesNotUpdateApp_postMigrationToPermissions() throws Exception {
- final NotificationChannel defaultChannel = mBinderService.getNotificationChannel(
- PKG_N_MR1, ActivityManager.getCurrentUser(), PKG_N_MR1,
- NotificationChannel.DEFAULT_CHANNEL_ID);
- defaultChannel.setImportance(IMPORTANCE_NONE);
-
- mBinderService.updateNotificationChannelForPackage(PKG_N_MR1, mUid, defaultChannel);
-
- verify(mPermissionHelper).setNotificationPermission(
- PKG_N_MR1, ActivityManager.getCurrentUser(), false, true);
- }
-
- @Test
- public void testPostNotification_appPermissionFixed() throws Exception {
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- when(mPermissionHelper.isPermissionFixed(PKG, 0)).thenReturn(true);
-
- NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG,
- "testPostNotification_appPermissionFixed", 0,
- temp.getNotification(), 0);
- waitForIdle();
- assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
- StatusBarNotification[] notifs =
- mBinderService.getActiveNotifications(PKG);
- assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue();
- }
-
- @Test
- public void testSummaryNotification_appPermissionFixed() {
- NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
- mService.addNotification(temp);
-
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
- when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true);
-
- NotificationRecord r = mService.createAutoGroupSummary(
- temp.getUserId(), temp.getSbn().getPackageName(), temp.getKey(), false);
-
- assertThat(r.isImportanceFixed()).isTrue();
- }
-
- @Test
- public void testMediaNotificationsBypassBlock() throws Exception {
- when(mAmi.getPendingIntentFlags(any(IIntentSender.class)))
- .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT);
- when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
-
- Notification.Builder nb = new Notification.Builder(
- mContext, mTestNotificationChannel.getId())
- .setContentTitle("foo")
- .setSmallIcon(android.R.drawable.sym_def_app_icon)
- .addAction(new Notification.Action.Builder(null, "test", null).build());
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
-
- // normal blocked notifications - blocked
- assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
-
- // just using the style - blocked
- nb.setStyle(new Notification.MediaStyle());
- sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
-
- // using the style, but incorrect type in session - blocked
- nb.setStyle(new Notification.MediaStyle());
- Bundle extras = new Bundle();
- extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, new Intent());
- nb.addExtras(extras);
- sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
-
- // style + media session - bypasses block
- nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
- sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
- }
-
- @Test
- public void testMediaNotificationsBypassBlock_atPost() throws Exception {
- when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
- when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
-
- Notification.Builder nb = new Notification.Builder(
- mContext, mTestNotificationChannel.getId())
- .setContentTitle("foo")
- .setSmallIcon(android.R.drawable.sym_def_app_icon)
- .addAction(new Notification.Action.Builder(null, "test", null).build());
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
-
- mService.addEnqueuedNotification(r);
- NotificationManagerService.PostNotificationRunnable runnable =
- mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
- waitForIdle();
-
- verify(mUsageStats).registerBlocked(any());
- verify(mUsageStats, never()).registerPostedByApp(any());
-
- // just using the style - blocked
- mService.clearNotifications();
- reset(mUsageStats);
- nb.setStyle(new Notification.MediaStyle());
- sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mService.addEnqueuedNotification(r);
- runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
- waitForIdle();
-
- verify(mUsageStats).registerBlocked(any());
- verify(mUsageStats, never()).registerPostedByApp(any());
-
- // style + media session - bypasses block
- mService.clearNotifications();
- reset(mUsageStats);
- nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
- sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mService.addEnqueuedNotification(r);
- runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
- waitForIdle();
-
- verify(mUsageStats, never()).registerBlocked(any());
- verify(mUsageStats).registerPostedByApp(any());
- }
-
- @Test
- public void testGetAllUsersNotificationPermissions() {
- // In this case, there are multiple users each with notification permissions (and also,
- // for good measure, some without).
- // make sure the collection returned contains info for all of them
- final List<UserInfo> userInfos = new ArrayList<>();
- userInfos.add(new UserInfo(0, "user0", 0));
- userInfos.add(new UserInfo(1, "user1", 0));
- userInfos.add(new UserInfo(2, "user2", 0));
- when(mUm.getUsers()).thenReturn(userInfos);
-
- // construct the permissions for each of them
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(),
- permissions1 = new ArrayMap<>();
- permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false));
- permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true));
- permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false));
- permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true));
- when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0);
- when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1);
- when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>());
-
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions =
- mService.getAllUsersNotificationPermissions();
- assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first);
- assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second);
- assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first);
- assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second);
- assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first);
- assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second);
- assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first);
- assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second);
- }
-}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index d89141c..5468220 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -1065,9 +1065,8 @@
}
@Test
- public void testApplyImportanceAdjustmentsForNonOemDefaultAppLockedChannels() {
+ public void testApplyImportanceAdjustments() {
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
- channel.setImportanceLockedByOEM(false);
StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index 46b47f4..3a352cb 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -88,51 +88,13 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, false);
+ mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, false);
PackageInfo testPkgInfo = new PackageInfo();
testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS };
when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
.thenReturn(testPkgInfo);
}
- // TODO (b/194833441): Remove when the migration is enabled
- @Test
- public void testMethodsThrowIfMigrationDisabled() throws IllegalAccessException,
- InvocationTargetException {
- PermissionHelper permHelper =
- new PermissionHelper(mPmi, mPackageManager, mPermManager, false, false);
-
- Method[] allMethods = PermissionHelper.class.getDeclaredMethods();
- for (Method method : allMethods) {
- if (Modifier.isPublic(method.getModifiers()) &&
- !Objects.equals("isMigrationEnabled", method.getName())) {
- Parameter[] params = method.getParameters();
- List<Object> args = Lists.newArrayListWithCapacity(params.length);
- for (int i = 0; i < params.length; i++) {
- Type type = params[i].getParameterizedType();
- if (type.getTypeName().equals("java.lang.String")) {
- args.add("");
- } else if (type.getTypeName().equals("boolean")){
- args.add(false);
- } else if (type.getTypeName().equals("int")) {
- args.add(1);
- } else if (type.getTypeName().equals(
- "com.android.server.notification.PermissionHelper$PackagePermission")) {
- args.add(null);
- }
- }
- try {
- method.invoke(permHelper, args.toArray());
- fail("Method should have thrown because migration flag is disabled");
- } catch (InvocationTargetException e) {
- if (!(e.getTargetException() instanceof IllegalStateException)) {
- throw e;
- }
- }
- }
- }
- }
-
@Test
public void testHasPermission() throws Exception {
when(mPmi.checkPostNotificationsPermissionGrantedOrLegacyAccess(anyInt()))
@@ -304,7 +266,7 @@
@Test
public void testSetNotificationPermission_pkgPerm_grantedByDefaultPermSet_allUserSet()
throws Exception {
- mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, true);
+ mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true);
when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
.thenReturn(PERMISSION_DENIED);
when(mPermManager.getPermissionFlags(anyString(),
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 63d7453..a5cec7e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -278,6 +278,14 @@
when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
+ appPermissions.put(new Pair(UID_P, PKG_P), new Pair(true, false));
+ appPermissions.put(new Pair(UID_O, PKG_O), new Pair(true, false));
+ appPermissions.put(new Pair(UID_N_MR1, PKG_N_MR1), new Pair(true, false));
+
+ when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM))
+ .thenReturn(appPermissions);
+
mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
@@ -289,6 +297,11 @@
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.build();
+
+ // make sure that the settings for review notification permissions are unset to begin with
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN);
}
private ByteArrayOutputStream writeXmlAndPurge(
@@ -403,6 +416,13 @@
NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
+ appPermissions.put(new Pair(uid0, package0), new Pair(false, false));
+ appPermissions.put(new Pair(uid10, package10), new Pair(true, false));
+
+ when(mPermissionHelper.getNotificationPermissionValues(10))
+ .thenReturn(appPermissions);
+
ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
// Reset state.
@@ -428,6 +448,12 @@
NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
+ appPermissions.put(new Pair(uid0, package0), new Pair(true, false));
+
+ when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM))
+ .thenReturn(appPermissions);
+
ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
// Reset state.
@@ -473,7 +499,6 @@
assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
- mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
UserHandle.USER_ALL, channel1.getId(), channel2.getId(),
@@ -484,7 +509,6 @@
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
- assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
assertEquals(channel1,
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
compareChannels(channel2,
@@ -545,8 +569,6 @@
mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
mHelper.setValidBubbleSent(PKG_P, UID_P);
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
-
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
USER_SYSTEM, channel1.getId(), channel2.getId(), channel3.getId(),
NotificationChannel.DEFAULT_CHANNEL_ID);
@@ -557,7 +579,6 @@
loadStreamXml(baos, true, USER_SYSTEM);
- assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
assertFalse(mHelper.hasSentInvalidMsg(PKG_N_MR1, UID_N_MR1));
@@ -596,7 +617,6 @@
@Test
public void testReadXml_oldXml_migrates() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -656,11 +676,17 @@
verify(mPermissionHelper).setNotificationPermission(nMr1Expected);
verify(mPermissionHelper).setNotificationPermission(oExpected);
verify(mPermissionHelper).setNotificationPermission(pExpected);
+
+ // verify that we also write a state for review_permissions_notification to eventually
+ // show a notification
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
}
@Test
public void testReadXml_oldXml_backup_migratesWhenPkgInstalled() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -738,8 +764,7 @@
}
@Test
- public void testReadXml_newXml_noMigration() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
+ public void testReadXml_newXml_noMigration_showPermissionNotification() throws Exception {
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -786,11 +811,73 @@
compareChannels(idp, mHelper.getNotificationChannel(PKG_P, UID_P, idp.getId(), false));
verify(mPermissionHelper, never()).setNotificationPermission(any());
+
+ // verify that we do, however, write a state for review_permissions_notification to
+ // eventually show a notification, since this XML version is older than the notification
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReadXml_newXml_noMigration_noPermissionNotification() throws Exception {
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
+
+ String xml = "<ranking version=\"4\">\n"
+ + "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
+ + "<channel id=\"idn\" name=\"name\" importance=\"2\"/>\n"
+ + "<channel id=\"miscellaneous\" name=\"Uncategorized\" />\n"
+ + "</package>\n"
+ + "<package name=\"" + PKG_O + "\" >\n"
+ + "<channel id=\"ido\" name=\"name2\" importance=\"2\" show_badge=\"true\"/>\n"
+ + "</package>\n"
+ + "<package name=\"" + PKG_P + "\" >\n"
+ + "<channel id=\"idp\" name=\"name3\" importance=\"4\" locked=\"2\" />\n"
+ + "</package>\n"
+ + "</ranking>\n";
+ NotificationChannel idn = new NotificationChannel("idn", "name", IMPORTANCE_LOW);
+ idn.setSound(null, new AudioAttributes.Builder()
+ .setUsage(USAGE_NOTIFICATION)
+ .setContentType(CONTENT_TYPE_SONIFICATION)
+ .setFlags(0)
+ .build());
+ idn.setShowBadge(false);
+ NotificationChannel ido = new NotificationChannel("ido", "name2", IMPORTANCE_LOW);
+ ido.setShowBadge(true);
+ ido.setSound(null, new AudioAttributes.Builder()
+ .setUsage(USAGE_NOTIFICATION)
+ .setContentType(CONTENT_TYPE_SONIFICATION)
+ .setFlags(0)
+ .build());
+ NotificationChannel idp = new NotificationChannel("idp", "name3", IMPORTANCE_HIGH);
+ idp.lockFields(2);
+ idp.setSound(null, new AudioAttributes.Builder()
+ .setUsage(USAGE_NOTIFICATION)
+ .setContentType(CONTENT_TYPE_SONIFICATION)
+ .setFlags(0)
+ .build());
+
+ loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM);
+
+ assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
+
+ assertEquals(idn, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, idn.getId(), false));
+ compareChannels(ido, mHelper.getNotificationChannel(PKG_O, UID_O, ido.getId(), false));
+ compareChannels(idp, mHelper.getNotificationChannel(PKG_P, UID_P, idp.getId(), false));
+
+ verify(mPermissionHelper, never()).setNotificationPermission(any());
+
+ // this XML is new enough, we should not be attempting to show a notification or anything
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
}
@Test
public void testReadXml_oldXml_migration_NoUid() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -824,7 +911,6 @@
@Test
public void testReadXml_newXml_noMigration_NoUid() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -857,7 +943,6 @@
@Test
public void testChannelXmlForNonBackup_postMigration() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -903,7 +988,7 @@
ByteArrayOutputStream baos = writeXmlAndPurge(
PKG_N_MR1, UID_N_MR1, false, USER_SYSTEM);
- String expected = "<ranking version=\"3\">\n"
+ String expected = "<ranking version=\"4\">\n"
+ "<package name=\"com.example.o\" show_badge=\"true\" "
+ "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
+ "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" uid=\"1111\">\n"
@@ -938,7 +1023,6 @@
@Test
public void testChannelXmlForBackup_postMigration() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -984,7 +1068,7 @@
ByteArrayOutputStream baos = writeXmlAndPurge(
PKG_N_MR1, UID_N_MR1, true, USER_SYSTEM);
- String expected = "<ranking version=\"3\">\n"
+ String expected = "<ranking version=\"4\">\n"
// Importance 0 because off in permissionhelper
+ "<package name=\"com.example.o\" importance=\"0\" show_badge=\"true\" "
+ "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
@@ -1025,7 +1109,6 @@
@Test
public void testChannelXmlForBackup_postMigration_noExternal() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -1067,7 +1150,7 @@
ByteArrayOutputStream baos = writeXmlAndPurge(
PKG_N_MR1, UID_N_MR1, true, USER_SYSTEM);
- String expected = "<ranking version=\"3\">\n"
+ String expected = "<ranking version=\"4\">\n"
// Importance 0 because off in permissionhelper
+ "<package name=\"com.example.o\" importance=\"0\" show_badge=\"true\" "
+ "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
@@ -1105,7 +1188,6 @@
@Test
public void testChannelXmlForBackup_postMigration_noLocalSettings() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory);
@@ -1121,7 +1203,7 @@
ByteArrayOutputStream baos = writeXmlAndPurge(
PKG_N_MR1, UID_N_MR1, true, USER_SYSTEM);
- String expected = "<ranking version=\"3\">\n"
+ String expected = "<ranking version=\"4\">\n"
// Packages that exist solely in permissionhelper
+ "<package name=\"" + PKG_P + "\" importance=\"3\" />\n"
+ "<package name=\"" + PKG_O + "\" importance=\"0\" />\n"
@@ -1227,6 +1309,12 @@
@Test
public void testBackupRestoreXml_withNullSoundUri() throws Exception {
+ ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
+ appPermissions.put(new Pair(UID_N_MR1, PKG_N_MR1), new Pair(true, false));
+
+ when(mPermissionHelper.getNotificationPermissionValues(USER_SYSTEM))
+ .thenReturn(appPermissions);
+
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
channel.setSound(null, mAudioAttributes);
@@ -1396,14 +1484,6 @@
}
@Test
- public void testCreateChannel_blocked() throws Exception {
- mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
-
- assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
- }
-
- @Test
public void testCreateChannel_badImportance() throws Exception {
try {
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
@@ -1467,12 +1547,10 @@
@Test
public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
- mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_UNSPECIFIED);
assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
- assertFalse(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
NotificationChannel defaultChannel = mHelper.getNotificationChannel(
PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
@@ -1490,8 +1568,6 @@
assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG_N_MR1,
UID_N_MR1));
- assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
- assertTrue(mHelper.getIsAppImportanceLocked(PKG_N_MR1, UID_N_MR1));
}
@Test
@@ -1516,9 +1592,6 @@
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
mHelper.getPackageVisibility(PKG_O, UID_O));
- assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O,
- UID_O));
- assertFalse(mHelper.getIsAppImportanceLocked(PKG_O, UID_O));
}
@Test
@@ -1553,8 +1626,6 @@
assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
mHelper.getPackageVisibility(PKG_N_MR1, UID_N_MR1));
- assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
- UID_N_MR1));
}
@Test
@@ -1939,8 +2010,9 @@
}
@Test
- public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() throws Exception {
+ public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
// create notification channel that can't bypass dnd
// expected result: areChannelsBypassingDnd = false
@@ -1953,7 +2025,6 @@
// create notification channel that can bypass dnd
// expected result: areChannelsBypassingDnd = true
- assertTrue(mHelper.getImportance(PKG_N_MR1, uid) != IMPORTANCE_NONE);
NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel2.setBypassDnd(true);
mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
@@ -1976,8 +2047,6 @@
@Test
public void testCreateAndUpdateChannelsBypassingDnd_permissionHelper() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
-
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
// create notification channel that can't bypass dnd
@@ -2000,10 +2069,8 @@
}
@Test
- public void testCreateAndDeleteCanChannelsBypassDnd_permissionHelper() throws Exception {
+ public void testCreateAndDeleteCanChannelsBypassDnd_permissionHelper() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
-
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
// create notification channel that can't bypass dnd
@@ -2037,8 +2104,9 @@
}
@Test
- public void testBlockedGroupDoesNotBypassDnd() throws Exception {
+ public void testBlockedGroupDoesNotBypassDnd() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
// start in a 'allowed to bypass dnd state'
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
@@ -2064,33 +2132,10 @@
}
@Test
- public void testBlockedAppsDoNotBypassDnd_localSettings() throws Exception {
+ public void testBlockedAppsDoNotBypassDnd_localSettings() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
-
- // start in a 'allowed to bypass dnd state'
- mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
- NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
- when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
- mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
- mPermissionHelper, mLogger,
- mAppOpsManager, mStatsEventBuilderFactory);
-
- mHelper.setImportance(PKG_N_MR1, uid, IMPORTANCE_NONE);
- // create notification channel that can bypass dnd, but app is blocked
- // expected result: areChannelsBypassingDnd = false
- NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
- channel2.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
- assertFalse(mHelper.areChannelsBypassingDnd());
- verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
- resetZenModeHelper();
- }
-
- @Test
- public void testBlockedAppsDoNotBypassDnd_permissionHelper() throws Exception {
- int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.hasPermission(uid)).thenReturn(false);
+
// start in a 'allowed to bypass dnd state'
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
@@ -2110,8 +2155,32 @@
}
@Test
- public void testUpdateCanChannelsBypassDnd() throws Exception {
+ public void testBlockedAppsDoNotBypassDnd_permissionHelper() {
int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(false);
+
+ // start in a 'allowed to bypass dnd state'
+ mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
+ NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
+ when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
+ mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
+ mPermissionHelper, mLogger,
+ mAppOpsManager, mStatsEventBuilderFactory);
+
+ // create notification channel that can bypass dnd, but app is blocked
+ // expected result: areChannelsBypassingDnd = false
+ NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ channel2.setBypassDnd(true);
+ mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+ assertFalse(mHelper.areChannelsBypassingDnd());
+ verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+ resetZenModeHelper();
+ }
+
+ @Test
+ public void testUpdateCanChannelsBypassDnd() {
+ int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1;
+ when(mPermissionHelper.hasPermission(uid)).thenReturn(true);
// create notification channel that can't bypass dnd
// expected result: areChannelsBypassingDnd = false
@@ -2329,8 +2398,8 @@
when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
// create records with the default channel for all user 0 and user 1 uids
- mHelper.getImportance(PKG_N_MR1, user0Uids[i]);
- mHelper.getImportance(PKG_N_MR1, user1Uids[i]);
+ mHelper.canShowBadge(PKG_N_MR1, user0Uids[i]);
+ mHelper.canShowBadge(PKG_N_MR1, user1Uids[i]);
}
mHelper.onUserRemoved(1);
@@ -2369,17 +2438,6 @@
}
@Test
- public void testOnPackageChanged_packageRemoval_importance() throws Exception {
- mHelper.setImportance(PKG_N_MR1, UID_N_MR1, NotificationManager.IMPORTANCE_HIGH);
-
- mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
- UID_N_MR1});
-
- assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
- UID_N_MR1));
- }
-
- @Test
public void testOnPackageChanged_packageRemoval_groups() throws Exception {
NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
@@ -2420,17 +2478,14 @@
mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
mHelper.createNotificationChannelGroup(
PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
- mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
mHelper.setShowBadge(PKG_O, UID_O, false);
mHelper.setAppImportanceLocked(PKG_O, UID_O);
mHelper.clearData(PKG_O, UID_O);
- assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O));
assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE);
assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2442,13 +2497,10 @@
mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
- assertTrue(channel.isImportanceLockedByOEM());
}
@Test
public void testRecordDefaults() throws Exception {
- assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1,
- UID_N_MR1));
assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
}
@@ -2684,69 +2736,7 @@
}
@Test
- public void testDumpJson_prePermissionMigration() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(false);
- // before the migration is active, we want to verify that:
- // - all notification importance info should come from package preferences
- // - if there are permissions granted or denied from packages PreferencesHelper doesn't
- // know about, those are ignored if migration is not enabled
-
- // package permissions map to be passed in
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
- appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
- appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs
- appPermissions.put(new Pair(UID_P, PKG_P), new Pair(true, false)); // in local prefs
- appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
-
- NotificationChannel channel1 =
- new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
- NotificationChannel channel3 = new NotificationChannel("id3", "name3", IMPORTANCE_HIGH);
-
- mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
- mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
-
- // in the json array, all of the individual package preferences are simply elements in the
- // values array. this set is to collect expected outputs for each of our packages.
- // the key/value pairs are: (userId, package name) -> expected importance
- ArrayMap<Pair<Integer, String>, String> expected = new ArrayMap<>();
- expected.put(new Pair(UserHandle.getUserId(UID_P), PKG_P), "LOW");
- expected.put(new Pair(UserHandle.getUserId(UID_O), PKG_O), "HIGH");
- expected.put(new Pair(UserHandle.getUserId(UID_N_MR1), PKG_N_MR1), "NONE");
-
- JSONArray actual = (JSONArray) mHelper.dumpJson(
- new NotificationManagerService.DumpFilter(), appPermissions)
- .get("PackagePreferencess");
- assertThat(actual.length()).isEqualTo(expected.size());
- for (int i = 0; i < actual.length(); i++) {
- JSONObject pkgInfo = actual.getJSONObject(i);
- Pair<Integer, String> pkgKey =
- new Pair(pkgInfo.getInt("userId"), pkgInfo.getString("packageName"));
- assertTrue(expected.containsKey(pkgKey));
- assertThat(pkgInfo.getString("importance")).isEqualTo(expected.get(pkgKey));
- }
-
- // also make sure that (more likely to actually happen) if we don't provide an array of
- // app preferences (and do null instead), the same thing happens, so do the same checks
- JSONArray actualWithNullInput = (JSONArray) mHelper.dumpJson(
- new NotificationManagerService.DumpFilter(), null)
- .get("PackagePreferencess");
- assertThat(actualWithNullInput.length()).isEqualTo(expected.size());
- for (int i = 0; i < actualWithNullInput.length(); i++) {
- JSONObject pkgInfo = actualWithNullInput.getJSONObject(i);
- Pair<Integer, String> pkgKey =
- new Pair(pkgInfo.getInt("userId"), pkgInfo.getString("packageName"));
- assertTrue(expected.containsKey(pkgKey));
- assertThat(pkgInfo.getString("importance")).isEqualTo(expected.get(pkgKey));
- }
- }
-
- @Test
public void testDumpJson_postPermissionMigration() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
// when getting a json dump, we want to verify that:
// - all notification importance info should come from the permission, even if the data
// isn't there yet but is present in package preferences
@@ -2768,11 +2758,8 @@
mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false);
mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
// in the json array, all of the individual package preferences are simply elements in the
// values array. this set is to collect expected outputs for each of our packages.
@@ -2811,11 +2798,10 @@
public void testDumpJson_givenNullInput_postMigration() throws Exception {
// simple test just to make sure nothing dies if we pass in null input even post migration
// for some reason, even though in practice this should not be how one calls this method
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- // some packages exist, with some importance info that won't be looked at
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
+ // some packages exist
+ mHelper.canShowBadge(PKG_O, UID_O);
+ mHelper.canShowBadge(PKG_P, UID_P);
JSONArray actual = (JSONArray) mHelper.dumpJson(
new NotificationManagerService.DumpFilter(), null)
@@ -2832,44 +2818,16 @@
}
@Test
- public void testDumpBansJson_prePermissionMigration() throws Exception {
- // confirm that the package bans that are in json are only from package preferences, and
- // not from the passed-in permissions map
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(false);
-
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
- appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
- appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs
- appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
-
- // package preferences: only PKG_P is banned
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
-
- // make sure that's the only thing in the package ban output
- JSONArray actual = mHelper.dumpBansJson(
- new NotificationManagerService.DumpFilter(), appPermissions);
- assertThat(actual.length()).isEqualTo(1);
-
- JSONObject ban = actual.getJSONObject(0);
- assertThat(ban.getInt("userId")).isEqualTo(UserHandle.getUserId(UID_P));
- assertThat(ban.getString("packageName")).isEqualTo(PKG_P);
- }
-
- @Test
public void testDumpBansJson_postPermissionMigration() throws Exception {
// confirm that the package bans that are in the output include all packages that
// have their permission set to false, and not based on PackagePreferences importance
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs
appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
- // package preferences: PKG_O not banned based on local importance, and PKG_P is
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
+ mHelper.canShowBadge(PKG_O, UID_O);
// expected output
ArraySet<Pair<Integer, String>> expected = new ArraySet<>();
@@ -2891,10 +2849,6 @@
@Test
public void testDumpBansJson_givenNullInput() throws Exception {
// no one should do this, but...
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
-
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
JSONArray actual = mHelper.dumpBansJson(
new NotificationManagerService.DumpFilter(), null);
@@ -2902,59 +2856,8 @@
}
@Test
- public void testDumpString_prePermissionMigration() {
- // confirm that the string resulting from dumpImpl contains only info from package prefs
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(false);
-
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
- appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
- appPermissions.put(new Pair(3, "third"), new Pair(false, true)); // not in local prefs
- appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
-
- // local package preferences: PKG_O is not banned even though the permissions would
- // indicate so
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
-
- // get dump output as a string so we can inspect the contents later
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- mHelper.dump(pw, "", new NotificationManagerService.DumpFilter(), appPermissions);
- pw.flush();
- String actual = sw.toString();
-
- // expected (substring) output for each preference
- ArrayList<String> expected = new ArrayList<>();
- expected.add(PKG_O + " (" + UID_O + ") importance=HIGH");
- expected.add(PKG_P + " (" + UID_P + ") importance=NONE");
-
- // make sure the things in app permissions do NOT show up
- ArrayList<String> notExpected = new ArrayList<>();
- notExpected.add("first (1) importance=DEFAULT");
- notExpected.add("third (3) importance=NONE");
- notExpected.add("userSet="); // no user-set information pre migration
-
- for (String exp : expected) {
- assertTrue(actual.contains(exp));
- }
-
- for (String notExp : notExpected) {
- assertFalse(actual.contains(notExp));
- }
-
- // also make sure it works the same if we pass in a null input
- StringWriter sw2 = new StringWriter();
- PrintWriter pw2 = new PrintWriter(sw2);
- mHelper.dump(pw2, "", new NotificationManagerService.DumpFilter(), null);
- pw.flush();
- String actualWithNullInput = sw2.toString();
- assertThat(actualWithNullInput).isEqualTo(actual);
- }
-
- @Test
public void testDumpString_postPermissionMigration() {
// confirm that the string resulting from dumpImpl contains only importances from permission
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
@@ -2962,8 +2865,8 @@
appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
// local package preferences
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
+ mHelper.canShowBadge(PKG_O, UID_O);
+ mHelper.canShowBadge(PKG_P, UID_P);
// get dump output as a string so we can inspect the contents later
StringWriter sw = new StringWriter();
@@ -2996,11 +2899,10 @@
@Test
public void testDumpString_givenNullInput() {
// test that this doesn't choke on null input
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
// local package preferences
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
+ mHelper.canShowBadge(PKG_O, UID_O);
+ mHelper.canShowBadge(PKG_P, UID_P);
// get dump output
StringWriter sw = new StringWriter();
@@ -3014,48 +2916,8 @@
}
@Test
- public void testDumpProto_prePermissionMigration() throws Exception {
- // test that dumping to proto gets the importances from the right place
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(false);
-
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
- appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
- appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs
- appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
-
- // local package preferences
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
-
- // expected output: only the local preferences
- // map format: (uid, package name) -> importance (int)
- ArrayMap<Pair<Integer, String>, Integer> expected = new ArrayMap<>();
- expected.put(new Pair(UID_O, PKG_O), IMPORTANCE_HIGH);
- expected.put(new Pair(UID_P, PKG_P), IMPORTANCE_NONE);
-
- // get the proto output and inspect its contents
- ProtoOutputStream proto = new ProtoOutputStream();
- mHelper.dump(proto, new NotificationManagerService.DumpFilter(), appPermissions);
-
- RankingHelperProto actual = RankingHelperProto.parseFrom(proto.getBytes());
- assertThat(actual.records.length).isEqualTo(expected.size());
- for (int i = 0; i < actual.records.length; i++) {
- RankingHelperProto.RecordProto record = actual.records[i];
- Pair<Integer, String> pkgKey = new Pair(record.uid, record.package_);
- assertTrue(expected.containsKey(pkgKey));
- assertThat(record.importance).isEqualTo(expected.get(pkgKey));
- }
-
- // also check that it's the same as passing in null input
- ProtoOutputStream proto2 = new ProtoOutputStream();
- mHelper.dump(proto2, new NotificationManagerService.DumpFilter(), null);
- assertThat(proto.getBytes()).isEqualTo(proto2.getBytes());
- }
-
- @Test
public void testDumpProto_postPermissionMigration() throws Exception {
// test that dumping to proto gets the importances from the right place
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
// permissions -- these should take precedence
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
@@ -3064,8 +2926,8 @@
appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
// local package preferences
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_LOW);
+ mHelper.canShowBadge(PKG_O, UID_O);
+ mHelper.canShowBadge(PKG_P, UID_P);
// expected output: all the packages, but only the ones provided via appPermissions
// should have importance set (aka not PKG_P)
@@ -3353,14 +3215,6 @@
}
@Test
- public void testAppBlockedLogging() {
- mHelper.setEnabled(PKG_N_MR1, 1020, false);
- assertEquals(1, mLogger.getCalls().size());
- assertEquals(
- NotificationChannelLogger.NotificationChannelEvent.APP_NOTIFICATIONS_BLOCKED,
- mLogger.get(0).event);
- }
- @Test
public void testXml_statusBarIcons_default() throws Exception {
String preQXml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
@@ -3441,7 +3295,7 @@
@Test
public void testIsDelegateAllowed_noDelegate() {
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
+ mHelper.canShowBadge(PKG_O, UID_O);
assertFalse(mHelper.isDelegateAllowed(PKG_O, UID_O, "whatever", 0));
}
@@ -3479,7 +3333,7 @@
@Test
public void testDelegateXml_noDelegate() throws Exception {
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
+ mHelper.canShowBadge(PKG_O, UID_O);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
@@ -3668,337 +3522,7 @@
}
@Test
- public void testLockChannelsForOEM_emptyList() {
- mHelper.lockChannelsForOEM(null);
- mHelper.lockChannelsForOEM(new String[0]);
- // no exception
- }
-
- @Test
- public void testLockChannelsForOEM_appWide() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
- // different uids, same package
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
- mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
- mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_onlyGivenPkg() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
- assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
- // different uids, same package
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
- mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
- mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet() {
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
- assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet() {
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
-
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
- // different uids, same package
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
- mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
- mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData()
- throws Exception {
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- final String xml = "<ranking version=\"1\">\n"
- + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
- + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
- + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
- + "</package>"
- + "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1 + "\" >\n"
- + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
- + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
- + "</package>"
- + "</ranking>";
- TypedXmlPullParser parser = Xml.newFastPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
- null);
- parser.nextTag();
- mHelper.readXml(parser, false, UserHandle.USER_ALL);
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false)
- .isImportanceLockedByOEM());
- assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "b", false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData_postMigration()
- throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- final String xml = "<ranking version=\"1\">\n"
- + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
- + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
- + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
- + "</package>"
- + "</ranking>";
- TypedXmlPullParser parser = Xml.newFastPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
- null);
- parser.nextTag();
- mHelper.readXml(parser, false, UserHandle.USER_ALL);
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData()
- throws Exception {
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
-
- final String xml = "<ranking version=\"1\">\n"
- + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n"
- + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
- + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
- + "</package>"
- + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n"
- + "<channel id=\"c\" name=\"c\" importance=\"3\"/>"
- + "</package>"
- + "</ranking>";
- TypedXmlPullParser parser = Xml.newFastPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
- null);
- parser.nextTag();
- mHelper.readXml(parser, false, UserHandle.USER_ALL);
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, "b", false)
- .isImportanceLockedByOEM());
- assertTrue(mHelper.getNotificationChannel(PKG_O, 30, "c", false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData_postMigration()
- throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
-
- final String xml = "<ranking version=\"1\">\n"
- + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n"
- + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
- + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
- + "</package>"
- + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n"
- + "<channel id=\"c\" name=\"c\" importance=\"3\"/>"
- + "</package>"
- + "</ranking>";
- TypedXmlPullParser parser = Xml.newFastPullParser();
- parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
- null);
- parser.nextTag();
- mHelper.readXml(parser, false, UserHandle.USER_ALL);
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false)
- .isImportanceLockedByOEM());
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "b", false)
- .isImportanceLockedByOEM());
- assertFalse(mHelper.getNotificationChannel(PKG_O, 30, "c", false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific_clearData() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.getImportance(PKG_O, UID_O);
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.clearData(PKG_O, UID_O);
-
- // it's back!
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- // and still locked
- assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelDoesNotExistYet_appWide() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
- assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
-
- assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
- assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelSpecific_clearData_postMigration() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.getImportance(PKG_O, UID_O);
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":" + a.getId()});
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.clearData(PKG_O, UID_O);
-
- // it's back!
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
- // and never locked
- assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelDoesNotExistYet_appWide_postMigration() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.createNotificationChannel(PKG_O, 3, b, true, false);
- assertFalse(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testLockChannelsForOEM_channelDoesNotExistYet_channelSpecific_postMigration() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O + ":a", PKG_O + ":b"});
-
- assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
- .isImportanceLockedByOEM());
-
- mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
- assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
- .isImportanceLockedByOEM());
- }
-
- @Test
- public void testUpdateNotificationChannel_oemLockedImportance() {
- NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-
- mHelper.lockChannelsForOEM(new String[] {PKG_O});
-
- NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
- update.setAllowBubbles(false);
-
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
-
- assertEquals(IMPORTANCE_HIGH,
- mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
- assertEquals(false,
- mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
-
- mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
-
- assertEquals(IMPORTANCE_HIGH,
- mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
- }
-
- @Test
public void testUpdateNotificationChannel_fixedPermission() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
@@ -4017,7 +3541,6 @@
@Test
public void testUpdateNotificationChannel_fixedPermission_butUserPreviouslyBlockedIt() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_NONE);
@@ -4036,7 +3559,6 @@
@Test
public void testUpdateNotificationChannel_fixedPermission_butAppAllowsIt() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
@@ -4056,7 +3578,6 @@
@Test
public void testUpdateNotificationChannel_notFixedPermission() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(false);
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
@@ -5236,56 +4757,7 @@
}
@Test
- public void testPullPackagePreferencesStats_prePermissionMigration() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(false);
-
- // build a collection of app permissions that should be passed in but ignored
- ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
- appPermissions.put(new Pair(1, "first"), new Pair(true, false)); // not in local prefs
- appPermissions.put(new Pair(3, "third"), new Pair(false, false)); // not in local prefs
- appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, false)); // in local prefs
-
- // package preferences: PKG_O not banned based on local importance, and PKG_P is
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
-
- // expected output. format: uid -> importance, as only uid (and not package name)
- // is in PackageNotificationPreferences
- ArrayMap<Integer, Integer> expected = new ArrayMap<>();
- expected.put(UID_O, IMPORTANCE_HIGH);
- expected.put(UID_P, IMPORTANCE_NONE);
-
- // unexpected output. these UIDs should not show up in the output at all
- ArraySet<Integer> unexpected = new ArraySet<>();
- unexpected.add(1);
- unexpected.add(3);
-
- ArrayList<StatsEvent> events = new ArrayList<>();
- mHelper.pullPackagePreferencesStats(events, appPermissions);
-
- for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
- if (builder.getAtomId() == PACKAGE_NOTIFICATION_PREFERENCES) {
- int uid = builder.getInt(PackageNotificationPreferences.UID_FIELD_NUMBER);
-
- // this shouldn't be any of the forbidden uids
- assertFalse(unexpected.contains(uid));
-
- // if it's one of the expected ids, then make sure the importance matches
- assertTrue(expected.containsKey(uid));
- assertThat(expected.get(uid)).isEqualTo(
- builder.getInt(PackageNotificationPreferences.IMPORTANCE_FIELD_NUMBER));
-
- // pre-migration, the userSet field will always default to false
- boolean userSet = builder.getBoolean(
- PackageNotificationPreferences.USER_SET_IMPORTANCE_FIELD_NUMBER);
- assertFalse(userSet);
- }
- }
- }
-
- @Test
public void testPullPackagePreferencesStats_postPermissionMigration() {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
// build a collection of app permissions that should be passed in but ignored
ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
@@ -5293,9 +4765,9 @@
appPermissions.put(new Pair(3, "third"), new Pair(false, true)); // not in local prefs
appPermissions.put(new Pair(UID_O, PKG_O), new Pair(false, true)); // in local prefs
- // package preferences: PKG_O not banned based on local importance, and PKG_P is
- mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_HIGH);
- mHelper.setImportance(PKG_P, UID_P, IMPORTANCE_NONE);
+ // local preferences
+ mHelper.canShowBadge(PKG_O, UID_O);
+ mHelper.canShowBadge(PKG_P, UID_P);
// expected output. format: uid -> importance, as only uid (and not package name)
// is in PackageNotificationPreferences
@@ -5357,27 +4829,4 @@
assertTrue((channelB.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
assertTrue((channelC.getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0);
}
-
- @Test
- public void testDefaultChannelUpdatesApp_preMigrationToPermissions() throws Exception {
- final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
- UID_N_MR1,
- NotificationChannel.DEFAULT_CHANNEL_ID, false);
- defaultChannel.setImportance(IMPORTANCE_NONE);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
-
- assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
- }
-
- @Test
- public void testDefaultChannelDoesNotUpdateApp_postMigrationToPermissions() throws Exception {
- when(mPermissionHelper.isMigrationEnabled()).thenReturn(true);
- final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG_N_MR1,
- UID_N_MR1,
- NotificationChannel.DEFAULT_CHANNEL_ID, false);
- defaultChannel.setImportance(IMPORTANCE_NONE);
- mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
-
- assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_N_MR1, UID_N_MR1));
- }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java
new file mode 100644
index 0000000..5a4ce5da
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsJobServiceTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.rule.ServiceTestRule;
+
+import com.android.server.LocalServices;
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+@RunWith(AndroidTestingRunner.class)
+public class ReviewNotificationPermissionsJobServiceTest extends UiServiceTestCase {
+ private ReviewNotificationPermissionsJobService mJobService;
+ private JobParameters mJobParams = new JobParameters(null,
+ ReviewNotificationPermissionsJobService.JOB_ID, null, null, null,
+ 0, false, false, null, null, null);
+
+ @Captor
+ ArgumentCaptor<JobInfo> mJobInfoCaptor;
+
+ @Mock
+ private JobScheduler mMockJobScheduler;
+
+ @Mock
+ private NotificationManagerInternal mMockNotificationManagerInternal;
+
+ @Rule
+ public final ServiceTestRule mServiceRule = new ServiceTestRule();
+
+ @Before
+ public void setUp() throws Exception {
+ mJobService = new ReviewNotificationPermissionsJobService();
+ mContext.addMockSystemService(JobScheduler.class, mMockJobScheduler);
+
+ // add NotificationManagerInternal to LocalServices
+ LocalServices.removeServiceForTest(NotificationManagerInternal.class);
+ LocalServices.addService(NotificationManagerInternal.class,
+ mMockNotificationManagerInternal);
+ }
+
+ @Test
+ public void testScheduleJob() {
+ // if asked, the job doesn't currently exist yet
+ when(mMockJobScheduler.getPendingJob(anyInt())).thenReturn(null);
+
+ final int rescheduleTimeMillis = 350; // arbitrary number
+
+ // attempt to schedule the job
+ ReviewNotificationPermissionsJobService.scheduleJob(mContext, rescheduleTimeMillis);
+ verify(mMockJobScheduler, times(1)).schedule(mJobInfoCaptor.capture());
+
+ // verify various properties of the job that is passed in to the job scheduler
+ JobInfo jobInfo = mJobInfoCaptor.getValue();
+ assertEquals(ReviewNotificationPermissionsJobService.JOB_ID, jobInfo.getId());
+ assertEquals(rescheduleTimeMillis, jobInfo.getMinLatencyMillis());
+ assertTrue(jobInfo.isPersisted()); // should continue after reboot
+ assertFalse(jobInfo.isPeriodic()); // one time
+ }
+
+ @Test
+ public void testOnStartJob() {
+ // the job need not be persisted after it does its work, so it'll return
+ // false
+ assertFalse(mJobService.onStartJob(mJobParams));
+
+ // verify that starting the job causes the notification to be sent
+ verify(mMockNotificationManagerInternal).sendReviewPermissionsNotification();
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsReceiverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsReceiverTest.java
new file mode 100644
index 0000000..12281a7
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ReviewNotificationPermissionsReceiverTest.java
@@ -0,0 +1,206 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ReviewNotificationPermissionsReceiverTest extends UiServiceTestCase {
+
+ // Simple mock class that just overrides the reschedule and cancel behavior so that it's easy
+ // to tell whether the receiver has sent requests to either reschedule or cancel the
+ // notification (or both).
+ private class MockReviewNotificationPermissionsReceiver
+ extends ReviewNotificationPermissionsReceiver {
+ boolean mCanceled = false;
+ boolean mRescheduled = false;
+
+ @Override
+ protected void cancelNotification(Context context) {
+ mCanceled = true;
+ }
+
+ @Override
+ protected void rescheduleNotification(Context context) {
+ mRescheduled = true;
+ }
+ }
+
+ private MockReviewNotificationPermissionsReceiver mReceiver;
+ private Intent mIntent;
+
+ @Before
+ public void setUp() {
+ mReceiver = new MockReviewNotificationPermissionsReceiver();
+ mIntent = new Intent(); // actions will be set in test cases
+ }
+
+ @Test
+ public void testReceive_remindMeLater_firstTime() {
+ // Test what happens when we receive a "remind me later" intent coming from
+ // a previously-not-interacted notification
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
+
+ // set up Intent action
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_REMIND);
+
+ // Upon receipt of the intent, the following things should happen:
+ // - notification rescheduled
+ // - notification explicitly canceled
+ // - settings state updated to indicate user has interacted
+ mReceiver.onReceive(mContext, mIntent);
+ assertTrue(mReceiver.mRescheduled);
+ assertTrue(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReceive_remindMeLater_laterTimes() {
+ // Test what happens when we receive a "remind me later" intent coming from
+ // a previously-interacted notification that has been rescheduled
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
+
+ // set up Intent action
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_REMIND);
+
+ // Upon receipt of the intent, the following things should still happen
+ // regardless of the fact that the user has interacted before:
+ // - notification rescheduled
+ // - notification explicitly canceled
+ // - settings state still indicate user has interacted
+ mReceiver.onReceive(mContext, mIntent);
+ assertTrue(mReceiver.mRescheduled);
+ assertTrue(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReceive_dismiss() {
+ // Test that dismissing the notification does *not* reschedule the notification,
+ // does cancel it, and writes that it has been dismissed to settings
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
+
+ // set up Intent action
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_DISMISS);
+
+ // send intent, watch what happens
+ mReceiver.onReceive(mContext, mIntent);
+ assertFalse(mReceiver.mRescheduled);
+ assertTrue(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_DISMISSED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReceive_notificationCanceled_firstSwipe() {
+ // Test the basic swipe away case: the first time the user swipes the notification
+ // away, it will not have been interacted with yet, so make sure it's rescheduled
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
+
+ // set up Intent action, would be called from notification's delete intent
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_CANCELED);
+
+ // send intent, make sure it gets:
+ // - rescheduled
+ // - not explicitly canceled, the notification was already canceled
+ // - noted that it's been interacted with
+ mReceiver.onReceive(mContext, mIntent);
+ assertTrue(mReceiver.mRescheduled);
+ assertFalse(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReceive_notificationCanceled_secondSwipe() {
+ // Test the swipe away case for a rescheduled notification: in this case
+ // it should not be rescheduled anymore
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_RESHOWN);
+
+ // set up Intent action, would be called from notification's delete intent
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_CANCELED);
+
+ // send intent, make sure it gets:
+ // - not rescheduled on the second+ swipe
+ // - not explicitly canceled, the notification was already canceled
+ // - mark as user interacted
+ mReceiver.onReceive(mContext, mIntent);
+ assertFalse(mReceiver.mRescheduled);
+ assertFalse(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_USER_INTERACTED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+
+ @Test
+ public void testReceive_notificationCanceled_fromDismiss() {
+ // Test that if the notification delete intent is called due to us canceling
+ // the notification from the receiver, we don't do anything extra
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_DISMISSED);
+
+ // set up Intent action, would be called from notification's delete intent
+ mIntent.setAction(NotificationManagerService.REVIEW_NOTIF_ACTION_CANCELED);
+
+ // nothing should happen, nothing at all
+ mReceiver.onReceive(mContext, mIntent);
+ assertFalse(mReceiver.mRescheduled);
+ assertFalse(mReceiver.mCanceled);
+ assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_DISMISSED,
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
+ NotificationManagerService.REVIEW_NOTIF_STATE_UNKNOWN));
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index 0bfd202..98c156e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -168,7 +168,8 @@
mock(StatsManager.class), mock(TelephonyManager.class),
mock(ActivityManagerInternal.class),
mock(MultiRateLimiter.class), mock(PermissionHelper.class),
- mock(UsageStatsManagerInternal.class), mock (TelecomManager.class));
+ mock(UsageStatsManagerInternal.class), mock (TelecomManager.class),
+ mock(NotificationChannelLogger.class));
} catch (SecurityException e) {
if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
throw e;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 908de34..b943275 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.Activity.RESULT_CANCELED;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.START_ABORTED;
import static android.app.ActivityManager.START_CANCELED;
@@ -784,6 +785,34 @@
}
/**
+ * This test ensures that {@link ActivityStarter#setTargetRootTaskIfNeeded} will task the
+ * adjacent task of indicated launch target into account. So the existing task will be launched
+ * into closer target.
+ */
+ @Test
+ public void testAdjustLaunchTargetWithAdjacentTask() {
+ // Create adjacent tasks and put one activity under it
+ final Task parent = new TaskBuilder(mSupervisor).build();
+ final Task adjacentParent = new TaskBuilder(mSupervisor).build();
+ parent.setAdjacentTaskFragment(adjacentParent, true);
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setParentTask(parent)
+ .setCreateTask(true).build();
+
+ // Launch the activity to its adjacent parent
+ final ActivityOptions options = ActivityOptions.makeBasic()
+ .setLaunchRootTask(adjacentParent.mRemoteToken.toWindowContainerToken());
+ prepareStarter(FLAG_ACTIVITY_NEW_TASK, false /* mockGetRootTask */)
+ .setReason("testAdjustLaunchTargetWithAdjacentTask")
+ .setIntent(activity.intent)
+ .setActivityOptions(options.toBundle())
+ .execute();
+
+ // Verify the activity will be launched into the original parent
+ assertTrue(activity.isDescendantOf(parent));
+ }
+
+ /**
* This test ensures that {@link ActivityStarter#setTargetRootTaskIfNeeded} will
* move the existing task to front if the current focused root task doesn't have running task.
*/
@@ -1297,6 +1326,22 @@
assertEquals(targetRecord.getLaunchIntoPipHostActivity(), sourceRecord);
}
+ @Test
+ public void testResultCanceledWhenNotAllowedStartingActivity() {
+ final ActivityStarter starter = prepareStarter(0, false);
+ final ActivityRecord targetRecord = new ActivityBuilder(mAtm).build();
+ final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).build();
+ targetRecord.resultTo = sourceRecord;
+
+ // Abort the activity start and ensure the sourceRecord gets the result (RESULT_CANCELED).
+ spyOn(starter);
+ doReturn(START_ABORTED).when(starter).isAllowedToStart(any(), anyBoolean(), any());
+ startActivityInner(starter, targetRecord, sourceRecord, null /* options */,
+ null /* inTask */, null /* inTaskFragment */);
+ verify(sourceRecord).sendResult(anyInt(), any(), anyInt(), eq(RESULT_CANCELED), any(),
+ any());
+ }
+
private static void startActivityInner(ActivityStarter starter, ActivityRecord target,
ActivityRecord source, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index 49cd343..873d9f3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -306,6 +306,7 @@
if (focus) {
doReturn(window.getWindowInfo().token)
.when(mWindowManagerInternal).getFocusedWindowToken();
+ doReturn(window).when(mWm).getFocusedWindowLocked();
}
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 263c936..c5f785e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1184,6 +1184,31 @@
}
@Test
+ public void testComputeImeParent_remoteControlTarget() throws Exception {
+ final DisplayContent dc = mDisplayContent;
+ WindowState app1 = createWindow(null, TYPE_BASE_APPLICATION, "app1");
+ WindowState app2 = createWindow(null, TYPE_BASE_APPLICATION, "app2");
+
+ dc.setImeLayeringTarget(app1);
+ dc.setImeInputTarget(app2);
+ dc.setRemoteInsetsController(createDisplayWindowInsetsController());
+ dc.getImeTarget(IME_TARGET_LAYERING).getWindow().setWindowingMode(
+ WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+ dc.getImeInputTarget().getWindowState().setWindowingMode(
+ WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+
+ // Expect ImeParent is null since ImeLayeringTarget and ImeInputTarget are different.
+ assertNull(dc.computeImeParent());
+
+ // ImeLayeringTarget and ImeInputTarget are updated to the same.
+ dc.setImeInputTarget(app1);
+ assertEquals(dc.getImeTarget(IME_TARGET_LAYERING), dc.getImeInputTarget());
+
+ // The ImeParent should be the display.
+ assertEquals(dc.getImeContainer().getParent().getSurfaceControl(), dc.computeImeParent());
+ }
+
+ @Test
public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception {
final DisplayContent dc = createNewDisplay();
diff --git a/services/voiceinteraction/TEST_MAPPING b/services/voiceinteraction/TEST_MAPPING
index bc8c639..22a6445 100644
--- a/services/voiceinteraction/TEST_MAPPING
+++ b/services/voiceinteraction/TEST_MAPPING
@@ -5,19 +5,6 @@
"options": [
{
"exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- // TODO(b/225076204): Remove the following four test cases after fixing the test fail.
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_createDetectorTwiceQuickly_triggerSuccess"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_onDetectFromExternalSource_success"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_createDetectorTwiceQuickly_triggerSuccess"
- },
- {
- "exclude-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest#testHotwordDetectionService_onDetectFromMic_success"
}
]
},
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index f31cdcb..43fcc8f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -323,6 +323,16 @@
new RoleObserver(mContext.getMainExecutor());
}
+ void handleUserStop(String packageName, int userHandle) {
+ synchronized (VoiceInteractionManagerServiceStub.this) {
+ ComponentName curInteractor = getCurInteractor(userHandle);
+ if (curInteractor != null && packageName.equals(curInteractor.getPackageName())) {
+ Slog.d(TAG, "switchImplementation for user stop.");
+ switchImplementationIfNeededLocked(true);
+ }
+ }
+ }
+
@Override
public @NonNull IVoiceInteractionSoundTriggerSession createSoundTriggerSessionAsOriginator(
@NonNull Identity originatorIdentity, IBinder client) {
@@ -2071,6 +2081,7 @@
}
PackageMonitor mPackageMonitor = new PackageMonitor() {
+
@Override
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
if (DEBUG) Slog.d(TAG, "onHandleForceStop uid=" + uid + " doit=" + doit);
@@ -2103,11 +2114,17 @@
}
setCurInteractor(null, userHandle);
+ // TODO: should not reset null here. But even remove this line, the
+ // initForUser() still reset it because the interactor will be null. Keep
+ // it now but we should still need to fix it.
setCurRecognizer(null, userHandle);
resetCurAssistant(userHandle);
initForUser(userHandle);
switchImplementationIfNeededLocked(true);
+ // When resetting the interactor, the recognizer and the assistant settings
+ // value, we also need to reset the assistant role to keep the values
+ // consistent. Clear the assistant role will reset to the default value.
Context context = getContext();
context.getSystemService(RoleManager.class).clearRoleHoldersAsUser(
RoleManager.ROLE_ASSISTANT, 0, UserHandle.of(userHandle),
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index edf1002..0558648 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -29,6 +29,7 @@
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
+import android.app.ApplicationExitInfo;
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.content.BroadcastReceiver;
@@ -38,6 +39,7 @@
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ServiceInfo;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger;
@@ -149,6 +151,32 @@
resetHotwordDetectionConnectionLocked();
}
}
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ Slog.d(TAG, "onBindingDied to " + name);
+ String packageName = name.getPackageName();
+ ParceledListSlice<ApplicationExitInfo> plistSlice = null;
+ try {
+ plistSlice = mAm.getHistoricalProcessExitReasons(packageName, 0, 1, mUser);
+ } catch (RemoteException e) {
+ // do nothing. The local binder so it can not throw it.
+ }
+ if (plistSlice == null) {
+ return;
+ }
+ List<ApplicationExitInfo> list = plistSlice.getList();
+ if (list.isEmpty()) {
+ return;
+ }
+ // TODO(b/229956310): Refactor the logic of PackageMonitor and onBindingDied
+ ApplicationExitInfo info = list.get(0);
+ if (info.getReason() == ApplicationExitInfo.REASON_USER_REQUESTED
+ && info.getSubReason() == ApplicationExitInfo.SUBREASON_STOP_APP) {
+ // only handle user stopped the application from the task manager
+ mServiceStub.handleUserStop(packageName, mUser);
+ }
+ }
};
VoiceInteractionManagerServiceImpl(Context context, Handler handler,
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 922eddb..884dcf2 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -76,6 +76,11 @@
private static boolean sIsUserExtendedLoggingEnabled = false;
/**
+ * Enabled in telecom testing to help gate log statements causing log spew.
+ */
+ private static boolean sIsUnitTestingEnabled = false;
+
+ /**
* The time when user-activated extended logging should be ended. Used to determine when
* extended logging should automatically be disabled.
*/
@@ -330,6 +335,20 @@
}
}
+ /**
+ * Enabled when tests are running to help gate log statements causing log spew.
+ *
+ * @param isEnabled {@code true} if running unit tests. false otherwise.
+ *
+ */
+ public static void setUnitTestingEnabled(boolean isEnabled) {
+ sIsUnitTestingEnabled = isEnabled;
+ }
+
+ public static boolean isUnitTestingEnabled() {
+ return sIsUnitTestingEnabled;
+ }
+
private static EventManager getEventManager() {
// Checking for null again outside of synchronization because we only need to synchronize
// during the lazy loading of the events logger. We don't need to synchronize elsewhere.
diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java
index e3485de..ec94f8a 100644
--- a/telecomm/java/android/telecom/PhoneAccountHandle.java
+++ b/telecomm/java/android/telecom/PhoneAccountHandle.java
@@ -46,6 +46,14 @@
* See {@link PhoneAccount}, {@link TelecomManager}.
*/
public final class PhoneAccountHandle implements Parcelable {
+ /**
+ * Expected component name of Telephony phone accounts; ONLY used to determine if we should log
+ * the phone account handle ID.
+ */
+ private static final ComponentName TELEPHONY_COMPONENT_NAME =
+ new ComponentName("com.android.phone",
+ "com.android.services.telephony.TelephonyConnectionService");
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 127403196)
private final ComponentName mComponentName;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -136,14 +144,23 @@
@Override
public String toString() {
- // Note: Log.pii called for mId as it can contain personally identifying phone account
- // information such as SIP account IDs.
- return new StringBuilder().append(mComponentName)
- .append(", ")
- .append(Log.pii(mId))
- .append(", ")
- .append(mUserHandle)
- .toString();
+ StringBuilder sb = new StringBuilder()
+ .append(mComponentName)
+ .append(", ");
+
+ if (TELEPHONY_COMPONENT_NAME.equals(mComponentName)) {
+ // Telephony phone account handles are now keyed by subscription id which is not
+ // sensitive.
+ sb.append(mId);
+ } else {
+ // Note: Log.pii called for mId as it can contain personally identifying phone account
+ // information such as SIP account IDs.
+ sb.append(Log.pii(mId));
+ }
+ sb.append(", ");
+ sb.append(mUserHandle);
+
+ return sb.toString();
}
@Override
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index f47cf33..e7d95e4 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -16,6 +16,8 @@
package android.telephony;
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
+
import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_ANOMALY_DETECTED;
import android.annotation.NonNull;
@@ -73,6 +75,7 @@
*
* This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is
* system protected. Invoking this method unless you are the system will result in an error.
+ * Carrier Id will be set as UNKNOWN_CARRIER_ID.
*
* @param eventId a fixed event ID that will be sent for each instance of the same event. This
* ID should be generated randomly.
@@ -81,6 +84,23 @@
* static and must not contain any sensitive information (especially PII).
*/
public static void reportAnomaly(@NonNull UUID eventId, String description) {
+ reportAnomaly(eventId, description, UNKNOWN_CARRIER_ID);
+ }
+
+ /**
+ * If enabled, build and send an intent to a Debug Service for logging.
+ *
+ * This method sends the {@link TelephonyManager#ACTION_ANOMALY_REPORTED} broadcast, which is
+ * system protected. Invoking this method unless you are the system will result in an error.
+ *
+ * @param eventId a fixed event ID that will be sent for each instance of the same event. This
+ * ID should be generated randomly.
+ * @param description an optional description, that if included will be used as the subject for
+ * identification and discussion of this event. This description should ideally be
+ * static and must not contain any sensitive information (especially PII).
+ * @param carrierId the carrier of the id associated with this event.
+ */
+ public static void reportAnomaly(@NonNull UUID eventId, String description, int carrierId) {
if (sContext == null) {
Rlog.w(TAG, "AnomalyReporter not yet initialized, dropping event=" + eventId);
return;
@@ -88,7 +108,7 @@
TelephonyStatsLog.write(
TELEPHONY_ANOMALY_DETECTED,
- 0, // TODO: carrier id needs to be populated
+ carrierId,
eventId.getLeastSignificantBits(),
eventId.getMostSignificantBits());
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e21301e..70fe6b1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4980,6 +4980,25 @@
KEY_PREFIX + "use_sip_uri_for_presence_subscribe_bool";
/**
+ * Flag indicating whether or not to use TEL URI when setting the entity uri field and
+ * contact element of each tuple.
+ *
+ * When {@code true}, the device sets the entity uri field and contact element to be
+ * TEL URI. This is done by first searching for the first TEL URI provided in
+ * p-associated-uri header. If there are no TEL URIs in the p-associated-uri header, we will
+ * convert the first SIP URI provided in the header to a TEL URI. If there are no URIs in
+ * the p-associated-uri header, we will then fall back to using the SIM card to generate the
+ * TEL URI.
+ * If {@code false}, the first URI provided in the p-associated-uri header is used,
+ * independent of the URI scheme. If there are no URIs available from p-associated-uri
+ * header, we will try to generate a SIP URI or TEL URI from the information provided by the
+ * SIM card, depending on the information available.
+ * @hide
+ */
+ public static final String KEY_USE_TEL_URI_FOR_PIDF_XML_BOOL =
+ KEY_PREFIX + "use_tel_uri_for_pidf_xml";
+
+ /**
* An integer key associated with the period of time in seconds the non-rcs capability
* information of each contact is cached on the device.
* <p>
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index fa6de1a..ac1f376 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1673,4 +1673,9 @@
return UNKNOWN;
}
}
+
+ /** @hide */
+ public static boolean isFailCauseExisting(@DataFailureCause int failCause) {
+ return sFailCauseMap.containsKey(failCause);
+ }
}
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 2833489..f65b7c2 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -1500,8 +1500,8 @@
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link ImsRcsManager.RcsImsCapabilityFlag} this method will always return
- * {@code true}.
+ * {@link ImsRcsManager.RcsImsCapabilityFlag} or if the device does not support IMS
+ * this method will always return {@code true}.
*
* @see CarrierConfigManager.Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL
* @return true if the device is provisioned for the capability or does not require
@@ -1530,8 +1530,8 @@
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link ImsRcsManager.RcsImsCapabilityFlag} this method
- * will always return {@code true}.
+ * {@link ImsRcsManager.RcsImsCapabilityFlag} or if the device does not support IMS
+ * this method will always return {@code true}.
*
* <p> Requires Permission:
* <ul>
@@ -1640,7 +1640,8 @@
* </ul>
*
* @return true if provisioning is required for the MMTEL capability and IMS
- * registration technology specified, false if it is not required.
+ * registration technology specified, false if it is not required or if the device does not
+ * support IMS.
*/
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
public boolean isProvisioningRequiredForCapability(
@@ -1667,7 +1668,8 @@
* </ul>
*
* @return true if provisioning is required for the RCS capability and IMS
- * registration technology specified, false if it is not required.
+ * registration technology specified, false if it is not required or if the device does not
+ * support IMS.
*/
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
public boolean isRcsProvisioningRequiredForCapability(
diff --git a/tests/ApkVerityTest/Android.bp b/tests/ApkVerityTest/Android.bp
index d4fa1dd..62e16a5 100644
--- a/tests/ApkVerityTest/Android.bp
+++ b/tests/ApkVerityTest/Android.bp
@@ -37,8 +37,8 @@
"general-tests",
"vts",
],
- data_device_bins: [
- "block_device_writer",
+ target_required: [
+ "block_device_writer_module",
],
data: [
":ApkVerityTestCertDer",
diff --git a/tests/ApkVerityTest/block_device_writer/Android.bp b/tests/ApkVerityTest/block_device_writer/Android.bp
index e5d009d..fdfa41f 100644
--- a/tests/ApkVerityTest/block_device_writer/Android.bp
+++ b/tests/ApkVerityTest/block_device_writer/Android.bp
@@ -24,7 +24,12 @@
}
cc_test {
- name: "block_device_writer",
+ // Depending on how the test runs, the executable may be uploaded to different location.
+ // Before the bug in the file pusher is fixed, workaround by making the name unique.
+ // See b/124718249#comment12.
+ name: "block_device_writer_module",
+ stem: "block_device_writer",
+
srcs: ["block_device_writer.cpp"],
cflags: [
"-D_FILE_OFFSET_BITS=64",
@@ -37,7 +42,22 @@
"libbase",
"libutils",
],
- compile_multilib: "first",
+ // For some reasons, cuttlefish (x86) uses x86_64 test suites for testing. Unfortunately, when
+ // the uploader does not pick up the executable from correct output location. The following
+ // workaround allows the test to:
+ // * upload the 32-bit exectuable for both 32 and 64 bits devices to use
+ // * refer to the same executable name in Java
+ // * no need to force the Java test to be archiecture specific.
+ //
+ // See b/145573317 for details.
+ multilib: {
+ lib32: {
+ suffix: "",
+ },
+ lib64: {
+ suffix: "64", // not really used
+ },
+ },
auto_gen_config: false,
test_suites: [
diff --git a/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java b/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java
index 730daf3..5c2c15b 100644
--- a/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java
+++ b/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java
@@ -32,7 +32,7 @@
* <p>To use this class, please push block_device_writer binary to /data/local/tmp.
* 1. In Android.bp, add:
* <pre>
- * data_device_bins: ["block_device_writer"],
+ * target_required: ["block_device_writer_module"],
* </pre>
* 2. In AndroidText.xml, add:
* <pre>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
new file mode 100644
index 0000000..16c4c25
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.wm.flicker.helpers
+
+import android.app.Instrumentation
+import android.support.test.launcherhelper.ILauncherStrategy
+import android.support.test.launcherhelper.LauncherStrategyFactory
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.parser.toFlickerComponent
+
+class ImeStateInitializeHelper @JvmOverloads constructor(
+ instr: Instrumentation,
+ launcherName: String = ActivityOptions.IME_ACTIVITY_INITIALIZE_LAUNCHER_NAME,
+ component: FlickerComponentName =
+ ActivityOptions.IME_ACTIVITY_INITIALIZE_COMPONENT_NAME.toFlickerComponent(),
+ launcherStrategy: ILauncherStrategy = LauncherStrategyFactory
+ .getInstance(instr)
+ .launcherStrategy
+) : StandardAppHelper(instr, launcherName, component, launcherStrategy)
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index 9643909..b897ca2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -28,6 +28,7 @@
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import com.android.server.wm.flicker.helpers.ImeStateInitializeHelper
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.traces.common.FlickerComponentName
import org.junit.FixMethodOrder
@@ -71,17 +72,20 @@
class LaunchAppShowImeOnStartTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
+ private val initializeApp = ImeStateInitializeHelper(instrumentation)
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
return FlickerBuilder(instrumentation).apply {
setup {
eachRun {
+ initializeApp.launchViaIntent()
this.setRotation(testSpec.startRotation)
}
}
teardown {
eachRun {
+ initializeApp.exit()
testApp.exit()
}
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 2842232..43aa4b1 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -52,6 +52,16 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+ <activity android:name=".ImeStateInitializeActivity"
+ android:theme="@style/no_starting_window"
+ android:windowSoftInputMode="stateAlwaysHidden"
+ android:label="ImeStateInitializeActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
<activity android:name=".SeamlessRotationActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.SeamlessRotationActivity"
android:theme="@style/CutoutShortEdges"
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml b/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
index 589df38..1d21fd5 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
@@ -42,4 +42,8 @@
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowSoftInputMode">stateUnchanged</item>
</style>
+
+ <style name="no_starting_window" parent="@android:style/Theme.DeviceDefault">
+ <item name="android:windowDisablePreview">true</item>
+ </style>
</resources>
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index e080709..6cda482 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -37,6 +37,11 @@
new ComponentName(FLICKER_APP_PACKAGE,
FLICKER_APP_PACKAGE + ".ImeActivity");
+ public static final String IME_ACTIVITY_INITIALIZE_LAUNCHER_NAME = "ImeStateInitializeActivity";
+ public static final ComponentName IME_ACTIVITY_INITIALIZE_COMPONENT_NAME =
+ new ComponentName(FLICKER_APP_PACKAGE,
+ FLICKER_APP_PACKAGE + ".ImeStateInitializeActivity");
+
public static final String SIMPLE_ACTIVITY_LAUNCHER_NAME = "SimpleApp";
public static final ComponentName SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME =
new ComponentName(FLICKER_APP_PACKAGE,
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeStateInitializeActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeStateInitializeActivity.java
new file mode 100644
index 0000000..4be79c4
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeStateInitializeActivity.java
@@ -0,0 +1,50 @@
+/*
+ * 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.wm.flicker.testapp;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A nop {@link Activity} to make sure that the test starts from a deterministic state.
+ *
+ * <p>Currently this {@link Activity} makes sure the following things</p>
+ * <li>
+ * <ul>Hide the software keyboard with
+ * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_STATE_ALWAYS_HIDDEN}</ul>
+ * <ul>Make sure that the navigation bar (if supported) is rendered with {@link Color#BLACK}.
+ * </ul>
+ * </li>
+ */
+public class ImeStateInitializeActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ final View view = new View(this);
+ view.setBackgroundColor(Color.WHITE);
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+
+ // Make sure that navigation bar is rendered with black (if supported).
+ getWindow().setNavigationBarColor(Color.BLACK);
+
+ setContentView(view);
+ }
+}
diff --git a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
index 3c6d54d..ae72247 100644
--- a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
@@ -29,7 +29,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
-import com.google.common.truth.Truth.assertThat
+import android.trust.test.lib.wait
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -74,9 +74,9 @@
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
+ uiDevice.wakeUp()
trustAgentRule.agent.grantTrust(
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
- uiDevice.wakeUp()
lockStateTrackingRule.assertLocked()
}
@@ -98,9 +98,9 @@
lockStateTrackingRule.assertLocked()
+ uiDevice.wakeUp()
trustAgentRule.agent.grantTrust(
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
- uiDevice.wakeUp()
lockStateTrackingRule.assertUnlocked()
}
@@ -116,6 +116,7 @@
uiDevice.sleep()
lockStateTrackingRule.assertLocked()
+ uiDevice.wakeUp()
Log.i(TAG, "Renewing trust and unlocking")
var result: GrantTrustResult? = null
@@ -124,10 +125,9 @@
Log.i(TAG, "Callback received; status=${it.status}")
result = it
}
- uiDevice.wakeUp()
lockStateTrackingRule.assertUnlocked()
- assertThat(result?.status).isEqualTo(STATUS_UNLOCKED_BY_GRANT)
+ wait("callback triggered") { result?.status == STATUS_UNLOCKED_BY_GRANT }
}
@Test
@@ -141,7 +141,6 @@
trustAgentRule.agent.revokeTrust()
await(500)
uiDevice.wakeUp()
- await(500)
trustAgentRule.agent.grantTrust(
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index dd60f17..8b7eadf9 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -349,8 +349,7 @@
size_t len;
const char16_t* str16 = tree.getText(&len);
if (str16) {
- text->text =
- ResTable::normalizeForOutput(util::Utf16ToUtf8(StringPiece16(str16, len)).c_str());
+ text->text = util::Utf16ToUtf8(StringPiece16(str16, len));
}
CHECK(!node_stack.empty());
node_stack.top()->AppendChild(std::move(text));
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index 3a2d656..6c717dc 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -139,19 +139,6 @@
EXPECT_THAT(attr->value, Eq("\""));
}
-TEST(XmlDomTest, XmlEscapeSingleQuotes) {
- std::unique_ptr<XmlResource> doc = test::BuildXmlDom(R"(
- <foo><![CDATA[oh no' (line=1001)
-E: this-is-not-an-element (line=88)
- T: 'blah]]></foo>)");
-
- Element* el = doc->root.get();
- Text* text = xml::NodeCast<xml::Text>(el->children[0].get());
- ASSERT_THAT(text, NotNull());
- EXPECT_THAT(text->text,
- Eq("oh no' (line=1001)\nE: this-is-not-an-element (line=88)\n T: 'blah"));
-}
-
class TestVisitor : public PackageAwareVisitor {
public:
using PackageAwareVisitor::Visit;