Merge "Fix IndexOutOfBoundsException while handle app crash" into udc-dev
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
index 6b3278f..4f5b620 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8572644"
+ build_id: "9653376"
target: "CtsShim"
source_file: "aosp_arm64/CtsShimPriv.apk"
}
@@ -8,7 +8,7 @@
version: ""
version_group: ""
git_project: "platform/frameworks/base"
- git_branch: "tm-dev"
+ git_branch: "master"
transform: TRANSFORM_NONE
transform_options {
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
index 34c9c4d..404bcac 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8572644"
+ build_id: "9653376"
target: "CtsShim"
source_file: "aosp_arm64/CtsShim.apk"
}
@@ -8,7 +8,7 @@
version: ""
version_group: ""
git_project: "platform/frameworks/base"
- git_branch: "tm-dev"
+ git_branch: "master"
transform: TRANSFORM_NONE
transform_options {
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb
new file mode 100644
index 0000000..e898091
--- /dev/null
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb
@@ -0,0 +1,15 @@
+drops {
+ android_build_drop {
+ build_id: "9653376"
+ target: "CtsShim"
+ source_file: "aosp_riscv64/CtsShimPriv.apk"
+ }
+ dest_file: "packages/CtsShim/apk//riscv64/CtsShimPriv.apk"
+ version: ""
+ version_group: ""
+ git_project: "platform/frameworks/base"
+ git_branch: "master"
+ transform: TRANSFORM_NONE
+ transform_options {
+ }
+}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb
new file mode 100644
index 0000000..04092366
--- /dev/null
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb
@@ -0,0 +1,15 @@
+drops {
+ android_build_drop {
+ build_id: "9653376"
+ target: "CtsShim"
+ source_file: "aosp_riscv64/CtsShim.apk"
+ }
+ dest_file: "packages/CtsShim/apk//riscv64/CtsShim.apk"
+ version: ""
+ version_group: ""
+ git_project: "platform/frameworks/base"
+ git_branch: "master"
+ transform: TRANSFORM_NONE
+ transform_options {
+ }
+}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
index 6897a02..045af02 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8572644"
+ build_id: "9653376"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShimPriv.apk"
}
@@ -8,7 +8,7 @@
version: ""
version_group: ""
git_project: "platform/frameworks/base"
- git_branch: "tm-dev"
+ git_branch: "master"
transform: TRANSFORM_NONE
transform_options {
}
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
index 6dfa7810..483b2f17 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8572644"
+ build_id: "9653376"
target: "CtsShim"
source_file: "aosp_x86_64/CtsShim.apk"
}
@@ -8,7 +8,7 @@
version: ""
version_group: ""
git_project: "platform/frameworks/base"
- git_branch: "tm-dev"
+ git_branch: "master"
transform: TRANSFORM_NONE
transform_options {
}
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java
index 2ab4324..cd92f3d 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobService.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java
@@ -166,7 +166,8 @@
* the job in the {@link #onStartJob(JobParameters)} callback.
* @param wantsReschedule {@code true} if this job should be rescheduled according
* to the back-off criteria specified when it was first scheduled; {@code false}
- * otherwise.
+ * otherwise. When {@code false} is returned for a periodic job,
+ * the job will be rescheduled according to its periodic policy.
*/
public final void jobFinished(JobParameters params, boolean wantsReschedule) {
mEngine.jobFinished(params, wantsReschedule);
@@ -217,7 +218,7 @@
* {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your
* job was executing the user toggled WiFi. Another example is if you had specified
* {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left
- * its idle maintenance window. There are many other reasons a job can be stopped early besides
+ * its idle state. There are many other reasons a job can be stopped early besides
* constraints no longer being satisfied. {@link JobParameters#getStopReason()} will return the
* reason this method was called. You are solely responsible for the behavior of your
* application upon receipt of this message; your app will likely start to misbehave if you
@@ -241,7 +242,8 @@
* included.
* @return {@code true} to indicate to the JobManager whether you'd like to reschedule
* this job based on the retry criteria provided at job creation-time; or {@code false}
- * to end the job entirely. Regardless of the value returned, your job must stop executing.
+ * to end the job entirely (or, for a periodic job, to reschedule it according to its
+ * requested periodic criteria). Regardless of the value returned, your job must stop executing.
*/
public abstract boolean onStopJob(JobParameters params);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index 69fe85e..430a1e2 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -35,6 +35,7 @@
import com.android.internal.annotations.VisibleForTesting;
import java.text.SimpleDateFormat;
+import java.util.Arrays;
import java.util.Date;
/**
@@ -264,7 +265,7 @@
return sb.toString();
}
- private static String policyIndexToString(int index) {
+ static String policyIndexToString(int index) {
switch (index) {
case REQUESTER_POLICY_INDEX:
return "requester";
@@ -400,4 +401,32 @@
proto.end(token);
}
+
+ /**
+ * Stores a snapshot of an alarm at any given time to be used for logging and diagnostics.
+ * This should intentionally avoid holding pointers to objects like {@link Alarm#operation}.
+ */
+ static class Snapshot {
+ final int mType;
+ final String mTag;
+ final long[] mPolicyWhenElapsed;
+
+ Snapshot(Alarm a) {
+ mType = a.type;
+ mTag = a.statsTag;
+ mPolicyWhenElapsed = Arrays.copyOf(a.mPolicyWhenElapsed, NUM_POLICIES);
+ }
+
+ void dump(IndentingPrintWriter pw, long nowElapsed) {
+ pw.print("type", typeToString(mType));
+ pw.print("tag", mTag);
+ pw.println();
+ pw.print("policyWhenElapsed:");
+ for (int i = 0; i < NUM_POLICIES; i++) {
+ pw.print(" " + policyIndexToString(i) + "=");
+ TimeUtils.formatDuration(mPolicyWhenElapsed[i], nowElapsed, pw);
+ }
+ pw.println();
+ }
+ }
}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index c76a43f..3772960 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -618,13 +618,13 @@
static final int REMOVE_REASON_LISTENER_BINDER_DIED = 5;
static final int REMOVE_REASON_LISTENER_CACHED = 6;
- final String mTag;
+ final Alarm.Snapshot mAlarmSnapshot;
final long mWhenRemovedElapsed;
final long mWhenRemovedRtc;
final int mRemoveReason;
RemovedAlarm(Alarm a, int removeReason, long nowRtc, long nowElapsed) {
- mTag = a.statsTag;
+ mAlarmSnapshot = new Alarm.Snapshot(a);
mRemoveReason = removeReason;
mWhenRemovedRtc = nowRtc;
mWhenRemovedElapsed = nowElapsed;
@@ -656,13 +656,21 @@
}
void dump(IndentingPrintWriter pw, long nowElapsed, SimpleDateFormat sdf) {
- pw.print("[tag", mTag);
- pw.print("reason", removeReasonToString(mRemoveReason));
+ pw.increaseIndent();
+
+ pw.print("Reason", removeReasonToString(mRemoveReason));
pw.print("elapsed=");
TimeUtils.formatDuration(mWhenRemovedElapsed, nowElapsed, pw);
pw.print(" rtc=");
pw.print(sdf.format(new Date(mWhenRemovedRtc)));
- pw.println("]");
+ pw.println();
+
+ pw.println("Snapshot:");
+ pw.increaseIndent();
+ mAlarmSnapshot.dump(pw, nowElapsed);
+ pw.decreaseIndent();
+
+ pw.decreaseIndent();
}
}
@@ -3088,7 +3096,9 @@
+ " does not belong to the calling uid " + callingUid);
}
synchronized (mLock) {
- removeLocked(callingPackage, REMOVE_REASON_ALARM_CANCELLED);
+ removeAlarmsInternalLocked(
+ a -> (a.matches(callingPackage) && a.creatorUid == callingUid),
+ REMOVE_REASON_ALARM_CANCELLED);
}
}
@@ -3503,15 +3513,16 @@
}
if (mRemovalHistory.size() > 0) {
- pw.println("Removal history: ");
+ pw.println("Removal history:");
pw.increaseIndent();
for (int i = 0; i < mRemovalHistory.size(); i++) {
UserHandle.formatUid(pw, mRemovalHistory.keyAt(i));
pw.println(":");
pw.increaseIndent();
final RemovedAlarm[] historyForUid = mRemovalHistory.valueAt(i).toArray();
- for (final RemovedAlarm removedAlarm : historyForUid) {
- removedAlarm.dump(pw, nowELAPSED, sdf);
+ for (int index = historyForUid.length - 1; index >= 0; index--) {
+ pw.print("#" + (historyForUid.length - index) + ": ");
+ historyForUid[index].dump(pw, nowELAPSED, sdf);
}
pw.decreaseIndent();
}
@@ -4285,10 +4296,25 @@
}
}
- boolean lookForPackageLocked(String packageName) {
- final ArrayList<Alarm> allAlarms = mAlarmStore.asList();
- for (final Alarm alarm : allAlarms) {
- if (alarm.matches(packageName)) {
+ @GuardedBy("mLock")
+ boolean lookForPackageLocked(String packageName, int uid) {
+ // This is called extremely rarely, e.g. when the user opens the force-stop page in settings
+ // so the loops using an iterator should be fine.
+ for (final Alarm alarm : mAlarmStore.asList()) {
+ if (alarm.matches(packageName) && alarm.creatorUid == uid) {
+ return true;
+ }
+ }
+ final ArrayList<Alarm> alarmsForUid = mPendingBackgroundAlarms.get(uid);
+ if (alarmsForUid != null) {
+ for (final Alarm alarm : alarmsForUid) {
+ if (alarm.matches(packageName)) {
+ return true;
+ }
+ }
+ }
+ for (final Alarm alarm : mPendingNonWakeupAlarms) {
+ if (alarm.matches(packageName) && alarm.creatorUid == uid) {
return true;
}
}
@@ -5269,7 +5295,7 @@
case Intent.ACTION_QUERY_PACKAGE_RESTART:
pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
for (String packageName : pkgList) {
- if (lookForPackageLocked(packageName)) {
+ if (lookForPackageLocked(packageName, uid)) {
setResultCode(Activity.RESULT_OK);
return;
}
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 89eb1a9..4477e94 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -1259,10 +1259,14 @@
final BackgroundStartPrivileges bsp =
activityManagerInternal.getBackgroundStartPrivileges(uid);
- final boolean balAllowed = bsp.allowsBackgroundActivityStarts();
if (DEBUG) {
- Slog.d(TAG, "Job " + job.toShortString() + " bal state: " + bsp);
+ Slog.d(TAG, "Job " + job.toShortString() + " bsp state: " + bsp);
}
+ // Intentionally use the background activity start BSP here instead of
+ // the full BAL check since the former is transient and better indicates that the
+ // user recently interacted with the app, while the latter includes
+ // permanent exceptions that don't warrant bypassing normal concurrency policy.
+ final boolean balAllowed = bsp.allowsBackgroundActivityStarts();
cachedPrivilegedState.put(uid,
balAllowed ? PRIVILEGED_STATE_BAL : PRIVILEGED_STATE_NONE);
return balAllowed;
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 08810b5..ea14640 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -31,7 +31,6 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
-import android.app.BackgroundStartPrivileges;
import android.app.IUidObserver;
import android.app.compat.CompatChanges;
import android.app.job.IJobScheduler;
@@ -1095,6 +1094,10 @@
synchronized (mLock) {
mUidToPackageCache.remove(uid);
}
+ } else {
+ synchronized (mJobSchedulerStub.mPersistCache) {
+ mJobSchedulerStub.mPersistCache.remove(pkgUid);
+ }
}
} else if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) {
if (DEBUG) {
@@ -1809,7 +1812,9 @@
private boolean cancelJobsForUid(int uid, boolean includeSourceApp,
boolean namespaceOnly, @Nullable String namespace,
@JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
- if (uid == Process.SYSTEM_UID) {
+ // Non-null system namespace means the cancelling is limited to the namespace
+ // and won't cause issues for the system at large.
+ if (uid == Process.SYSTEM_UID && (!namespaceOnly || namespace == null)) {
Slog.wtfStack(TAG, "Can't cancel all jobs for system uid");
return false;
}
@@ -3782,7 +3787,8 @@
return canPersist;
}
- private int validateJob(@NonNull JobInfo job, int callingUid, int sourceUserId,
+ private int validateJob(@NonNull JobInfo job, int callingUid, int callingPid,
+ int sourceUserId,
@Nullable String sourcePkgName, @Nullable JobWorkItem jobWorkItem) {
final boolean rejectNegativeNetworkEstimates = CompatChanges.isChangeEnabled(
JobInfo.REJECT_NEGATIVE_NETWORK_ESTIMATES, callingUid);
@@ -3815,6 +3821,8 @@
}
// We aim to check the permission of both the source and calling app so that apps
// don't attempt to bypass the permission by using other apps to do the work.
+ boolean isInStateToScheduleUiJobSource = false;
+ final String callingPkgName = job.getService().getPackageName();
if (sourceUid != -1) {
// Check the permission of the source app.
final int sourceResult =
@@ -3822,8 +3830,13 @@
if (sourceResult != JobScheduler.RESULT_SUCCESS) {
return sourceResult;
}
+ final int sourcePid =
+ callingUid == sourceUid && callingPkgName.equals(sourcePkgName)
+ ? callingPid : -1;
+ isInStateToScheduleUiJobSource = isInStateToScheduleUserInitiatedJobs(
+ sourceUid, sourcePid, sourcePkgName);
}
- final String callingPkgName = job.getService().getPackageName();
+ boolean isInStateToScheduleUiJobCalling = false;
if (callingUid != sourceUid || !callingPkgName.equals(sourcePkgName)) {
// Source app is different from calling app. Make sure the calling app also has
// the permission.
@@ -3832,25 +3845,17 @@
if (callingResult != JobScheduler.RESULT_SUCCESS) {
return callingResult;
}
+ // Avoid rechecking the state if the source app is able to schedule the job.
+ if (!isInStateToScheduleUiJobSource) {
+ isInStateToScheduleUiJobCalling = isInStateToScheduleUserInitiatedJobs(
+ callingUid, callingPid, callingPkgName);
+ }
}
- final int uid = sourceUid != -1 ? sourceUid : callingUid;
- final int procState = mActivityManagerInternal.getUidProcessState(uid);
- if (DEBUG) {
- Slog.d(TAG, "Uid " + uid + " proc state="
- + ActivityManager.procStateToString(procState));
- }
- if (procState != ActivityManager.PROCESS_STATE_TOP) {
- final BackgroundStartPrivileges bsp =
- mActivityManagerInternal.getBackgroundStartPrivileges(uid);
- if (DEBUG) {
- Slog.d(TAG, "Uid " + uid + ": " + bsp);
- }
- if (!bsp.allowsBackgroundActivityStarts()) {
- Slog.e(TAG,
- "Uid " + uid + " not in a state to schedule user-initiated jobs");
- return JobScheduler.RESULT_FAILURE;
- }
+ if (!isInStateToScheduleUiJobSource && !isInStateToScheduleUiJobCalling) {
+ Slog.e(TAG, "Uid(s) " + sourceUid + "/" + callingUid
+ + " not in a state to schedule user-initiated jobs");
+ return JobScheduler.RESULT_FAILURE;
}
}
if (jobWorkItem != null) {
@@ -3896,6 +3901,24 @@
return JobScheduler.RESULT_SUCCESS;
}
+ private boolean isInStateToScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ final int procState = mActivityManagerInternal.getUidProcessState(uid);
+ if (DEBUG) {
+ Slog.d(TAG, "Uid " + uid + " proc state="
+ + ActivityManager.procStateToString(procState));
+ }
+ if (procState == ActivityManager.PROCESS_STATE_TOP) {
+ return true;
+ }
+ final boolean canScheduleUiJobsInBg =
+ mActivityManagerInternal.canScheduleUserInitiatedJobs(uid, pid, pkgName);
+ if (DEBUG) {
+ Slog.d(TAG, "Uid " + uid
+ + " AM.canScheduleUserInitiatedJobs= " + canScheduleUiJobsInBg);
+ }
+ return canScheduleUiJobsInBg;
+ }
+
// IJobScheduler implementation
@Override
public int schedule(String namespace, JobInfo job) throws RemoteException {
@@ -3908,7 +3931,7 @@
enforceValidJobRequest(uid, pid, job);
- final int result = validateJob(job, uid, -1, null, null);
+ final int result = validateJob(job, uid, pid, -1, null, null);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
@@ -3941,7 +3964,7 @@
throw new NullPointerException("work is null");
}
- final int result = validateJob(job, uid, -1, null, work);
+ final int result = validateJob(job, uid, pid, -1, null, work);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
@@ -3963,6 +3986,7 @@
public int scheduleAsPackage(String namespace, JobInfo job, String packageName, int userId,
String tag) throws RemoteException {
final int callerUid = Binder.getCallingUid();
+ final int callerPid = Binder.getCallingPid();
if (DEBUG) {
Slog.d(TAG, "Caller uid " + callerUid + " scheduling job: " + job.toString()
+ " on behalf of " + packageName + "/");
@@ -3979,7 +4003,7 @@
+ " not permitted to schedule jobs for other apps");
}
- int result = validateJob(job, callerUid, userId, packageName, null);
+ int result = validateJob(job, callerUid, callerPid, userId, packageName, null);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 4c339ac..f3203ca 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -35,7 +35,6 @@
import android.app.job.JobWorkItem;
import android.app.usage.UsageStatsManagerInternal;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledAfter;
import android.content.ComponentName;
import android.content.Context;
@@ -97,9 +96,7 @@
* Whether to trigger an ANR when apps are slow to respond on pre-UDC APIs and functionality.
*/
@ChangeId
- @Disabled
- // TODO(258236856): Enable after test is fixed
- // @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
private static final long ANR_PRE_UDC_APIS_ON_SLOW_RESPONSES = 258236856L;
private static final String TAG = "JobServiceContext";
@@ -465,22 +462,36 @@
mExecutionStartTimeElapsed - job.enqueueTime,
job.getJob().isUserInitiated(),
job.shouldTreatAsUserInitiatedJob());
+ final String sourcePackage = job.getSourcePackageName();
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+ final String componentPackage = job.getServiceComponent().getPackageName();
+ String traceTag = "*job*<" + job.getSourceUid() + ">" + sourcePackage;
+ if (!sourcePackage.equals(componentPackage)) {
+ traceTag += ":" + componentPackage;
+ }
+ traceTag += "/" + job.getServiceComponent().getShortClassName();
+ if (!componentPackage.equals(job.serviceProcessName)) {
+ traceTag += "$" + job.serviceProcessName;
+ }
+ if (job.getNamespace() != null) {
+ traceTag += "@" + job.getNamespace();
+ }
+ traceTag += "#" + job.getJobId();
+
// Use the context's ID to distinguish traces since there'll only be one job
// running per context.
Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "JobScheduler",
- job.getTag(), getId());
+ traceTag, getId());
}
try {
mBatteryStats.noteJobStart(job.getBatteryName(), job.getSourceUid());
} catch (RemoteException e) {
// Whatever.
}
- final String jobPackage = job.getSourcePackageName();
final int jobUserId = job.getSourceUserId();
UsageStatsManagerInternal usageStats =
LocalServices.getService(UsageStatsManagerInternal.class);
- usageStats.setLastJobRunTime(jobPackage, jobUserId, mExecutionStartTimeElapsed);
+ usageStats.setLastJobRunTime(sourcePackage, jobUserId, mExecutionStartTimeElapsed);
mAvailable = false;
mStoppedReason = null;
mStoppedTime = 0;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 17dde90..8585740 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -2124,9 +2124,9 @@
sb.append(" READY");
} else {
sb.append(" satisfied:0x").append(Integer.toHexString(satisfiedConstraints));
+ final int requiredConstraints = mRequiredConstraintsOfInterest | IMPLICIT_CONSTRAINTS;
sb.append(" unsatisfied:0x").append(Integer.toHexString(
- (satisfiedConstraints & (mRequiredConstraintsOfInterest | IMPLICIT_CONSTRAINTS))
- ^ mRequiredConstraintsOfInterest));
+ (satisfiedConstraints & requiredConstraints) ^ requiredConstraints));
}
sb.append("}");
return sb.toString();
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
index a6d064c..4d8b3e1 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
@@ -38,6 +38,7 @@
import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
@@ -77,6 +78,7 @@
import static android.app.tare.EconomyManager.KEY_AM_MAX_SATIATED_BALANCE;
import static android.app.tare.EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT;
import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED;
+import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP;
import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP;
import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT;
import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX;
@@ -145,6 +147,7 @@
};
private long mMinSatiatedBalanceExempted;
+ private long mMinSatiatedBalanceHeadlessSystemApp;
private long mMinSatiatedBalanceOther;
private long mMaxSatiatedBalance;
private long mInitialSatiatedConsumptionLimit;
@@ -179,6 +182,9 @@
if (mIrs.isPackageExempted(userId, pkgName)) {
return mMinSatiatedBalanceExempted;
}
+ if (mIrs.isHeadlessSystemApp(pkgName)) {
+ return mMinSatiatedBalanceHeadlessSystemApp;
+ }
// TODO: take other exemptions into account
return mMinSatiatedBalanceOther;
}
@@ -242,9 +248,14 @@
mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
+ mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+ KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
+ mMinSatiatedBalanceOther);
mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
- KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
- mMinSatiatedBalanceOther);
+ KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
+ DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
+ mMinSatiatedBalanceHeadlessSystemApp);
mMaxSatiatedBalance = getConstantAsCake(mParser, properties,
KEY_AM_MAX_SATIATED_BALANCE, DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
index ffb2c03..1c915bc 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -205,6 +205,11 @@
@GuardedBy("mLock")
private final SparseArrayMap<String, ArraySet<String>> mInstallers = new SparseArrayMap<>();
+ /** The package name of the wellbeing app. */
+ @GuardedBy("mLock")
+ @Nullable
+ private String mWellbeingPackage;
+
private volatile boolean mHasBattery = true;
@EconomyManager.EnabledMode
private volatile int mEnabledMode;
@@ -496,6 +501,20 @@
}
}
+ boolean isHeadlessSystemApp(@NonNull String pkgName) {
+ if (pkgName == null) {
+ Slog.wtfStack(TAG, "isHeadlessSystemApp called with null package");
+ return false;
+ }
+ synchronized (mLock) {
+ // The wellbeing app is pre-set on the device, not expected to be interacted with
+ // much by the user, but can be expected to do work in the background on behalf of
+ // the user. As such, it's a pseudo-headless system app, so treat it as a headless
+ // system app.
+ return pkgName.equals(mWellbeingPackage);
+ }
+ }
+
boolean isPackageExempted(final int userId, @NonNull String pkgName) {
synchronized (mLock) {
return mExemptedApps.contains(pkgName);
@@ -1097,6 +1116,9 @@
}
synchronized (mLock) {
registerListeners();
+ // As of Android UDC, users can't change the wellbeing package, so load it once
+ // as soon as possible and don't bother trying to update it afterwards.
+ mWellbeingPackage = mPackageManager.getWellbeingPackageName();
mCurrentBatteryLevel = getCurrentBatteryLevel();
// Get the current battery presence, if available. This would succeed if TARE is
// toggled long after boot.
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
index c2a6e43..526e876 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
@@ -43,6 +43,7 @@
import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
+import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES;
@@ -90,6 +91,7 @@
import static android.app.tare.EconomyManager.KEY_JS_MAX_SATIATED_BALANCE;
import static android.app.tare.EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED;
+import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER;
import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP;
import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT;
@@ -158,6 +160,7 @@
};
private long mMinSatiatedBalanceExempted;
+ private long mMinSatiatedBalanceHeadlessSystemApp;
private long mMinSatiatedBalanceOther;
private long mMinSatiatedBalanceIncrementalAppUpdater;
private long mMaxSatiatedBalance;
@@ -194,6 +197,8 @@
final long baseBalance;
if (mIrs.isPackageExempted(userId, pkgName)) {
baseBalance = mMinSatiatedBalanceExempted;
+ } else if (mIrs.isHeadlessSystemApp(pkgName)) {
+ baseBalance = mMinSatiatedBalanceHeadlessSystemApp;
} else {
baseBalance = mMinSatiatedBalanceOther;
}
@@ -276,9 +281,14 @@
mMinSatiatedBalanceOther = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
+ mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(mParser, properties,
+ KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
+ mMinSatiatedBalanceOther);
mMinSatiatedBalanceExempted = getConstantAsCake(mParser, properties,
- KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
- mMinSatiatedBalanceOther);
+ KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
+ DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
+ mMinSatiatedBalanceHeadlessSystemApp);
mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(mParser, properties,
KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
diff --git a/core/api/current.txt b/core/api/current.txt
index 70dcd54..4332d21 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -83,6 +83,7 @@
field public static final String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY";
field public static final String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
+ field public static final String CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS = "android.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS";
field public static final String CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS = "android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS";
field public static final String CREDENTIAL_MANAGER_SET_ORIGIN = "android.permission.CREDENTIAL_MANAGER_SET_ORIGIN";
field public static final String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
@@ -2014,18 +2015,14 @@
field public static final int system_on_primary_container_dark;
field public static final int system_on_primary_container_light;
field public static final int system_on_primary_dark;
- field public static final int system_on_primary_fixed_dark;
- field public static final int system_on_primary_fixed_light;
- field public static final int system_on_primary_fixed_variant_dark;
- field public static final int system_on_primary_fixed_variant_light;
+ field public static final int system_on_primary_fixed;
+ field public static final int system_on_primary_fixed_variant;
field public static final int system_on_primary_light;
field public static final int system_on_secondary_container_dark;
field public static final int system_on_secondary_container_light;
field public static final int system_on_secondary_dark;
- field public static final int system_on_secondary_fixed_dark;
- field public static final int system_on_secondary_fixed_light;
- field public static final int system_on_secondary_fixed_variant_dark;
- field public static final int system_on_secondary_fixed_variant_light;
+ field public static final int system_on_secondary_fixed;
+ field public static final int system_on_secondary_fixed_variant;
field public static final int system_on_secondary_light;
field public static final int system_on_surface_dark;
field public static final int system_on_surface_light;
@@ -2034,10 +2031,8 @@
field public static final int system_on_tertiary_container_dark;
field public static final int system_on_tertiary_container_light;
field public static final int system_on_tertiary_dark;
- field public static final int system_on_tertiary_fixed_dark;
- field public static final int system_on_tertiary_fixed_light;
- field public static final int system_on_tertiary_fixed_variant_dark;
- field public static final int system_on_tertiary_fixed_variant_light;
+ field public static final int system_on_tertiary_fixed;
+ field public static final int system_on_tertiary_fixed_variant;
field public static final int system_on_tertiary_light;
field public static final int system_outline_dark;
field public static final int system_outline_light;
@@ -2056,18 +2051,14 @@
field public static final int system_primary_container_dark;
field public static final int system_primary_container_light;
field public static final int system_primary_dark;
- field public static final int system_primary_fixed_dark;
- field public static final int system_primary_fixed_dim_dark;
- field public static final int system_primary_fixed_dim_light;
- field public static final int system_primary_fixed_light;
+ field public static final int system_primary_fixed;
+ field public static final int system_primary_fixed_dim;
field public static final int system_primary_light;
field public static final int system_secondary_container_dark;
field public static final int system_secondary_container_light;
field public static final int system_secondary_dark;
- field public static final int system_secondary_fixed_dark;
- field public static final int system_secondary_fixed_dim_dark;
- field public static final int system_secondary_fixed_dim_light;
- field public static final int system_secondary_fixed_light;
+ field public static final int system_secondary_fixed;
+ field public static final int system_secondary_fixed_dim;
field public static final int system_secondary_light;
field public static final int system_surface_bright_dark;
field public static final int system_surface_bright_light;
@@ -2090,10 +2081,8 @@
field public static final int system_tertiary_container_dark;
field public static final int system_tertiary_container_light;
field public static final int system_tertiary_dark;
- field public static final int system_tertiary_fixed_dark;
- field public static final int system_tertiary_fixed_dim_dark;
- field public static final int system_tertiary_fixed_dim_light;
- field public static final int system_tertiary_fixed_light;
+ field public static final int system_tertiary_fixed;
+ field public static final int system_tertiary_fixed_dim;
field public static final int system_tertiary_light;
field public static final int system_text_hint_inverse_dark;
field public static final int system_text_hint_inverse_light;
@@ -13669,7 +13658,9 @@
method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
method public void createCredential(@NonNull android.credentials.CreateCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CreateCredentialException>);
method public void getCredential(@NonNull android.credentials.GetCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
+ method public void getCredential(@NonNull android.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
method public boolean isEnabledCredentialProviderService(@NonNull android.content.ComponentName);
+ method public void prepareGetCredential(@NonNull android.credentials.GetCredentialRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.PrepareGetCredentialResponse,android.credentials.GetCredentialException>);
method public void registerCredentialDescription(@NonNull android.credentials.RegisterCredentialDescriptionRequest);
method public void unregisterCredentialDescription(@NonNull android.credentials.UnregisterCredentialDescriptionRequest);
}
@@ -13734,6 +13725,16 @@
field @NonNull public static final android.os.Parcelable.Creator<android.credentials.GetCredentialResponse> CREATOR;
}
+ public final class PrepareGetCredentialResponse {
+ method @NonNull public android.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle getPendingGetCredentialHandle();
+ method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasAuthenticationResults();
+ method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasCredentialResults(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasRemoteResults();
+ }
+
+ public static final class PrepareGetCredentialResponse.PendingGetCredentialHandle {
+ }
+
public final class RegisterCredentialDescriptionRequest implements android.os.Parcelable {
ctor public RegisterCredentialDescriptionRequest(@NonNull android.credentials.CredentialDescription);
ctor public RegisterCredentialDescriptionRequest(@NonNull java.util.Set<android.credentials.CredentialDescription>);
@@ -40578,7 +40579,7 @@
package android.service.credentials {
- public class Action implements android.os.Parcelable {
+ public final class Action implements android.os.Parcelable {
ctor public Action(@NonNull android.app.slice.Slice);
method public int describeContents();
method @NonNull public android.app.slice.Slice getSlice();
@@ -40586,7 +40587,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.Action> CREATOR;
}
- public class BeginCreateCredentialRequest implements android.os.Parcelable {
+ public final class BeginCreateCredentialRequest implements android.os.Parcelable {
ctor public BeginCreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle, @Nullable android.service.credentials.CallingAppInfo);
ctor public BeginCreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle);
method public int describeContents();
@@ -40614,7 +40615,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.PROVIDE_REMOTE_CREDENTIALS) public android.service.credentials.BeginCreateCredentialResponse.Builder setRemoteCreateEntry(@Nullable android.service.credentials.RemoteEntry);
}
- public class BeginGetCredentialOption implements android.os.Parcelable {
+ public final class BeginGetCredentialOption implements android.os.Parcelable {
ctor public BeginGetCredentialOption(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
method public int describeContents();
method @NonNull public android.os.Bundle getCandidateQueryData();
@@ -40693,7 +40694,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CreateCredentialRequest> CREATOR;
}
- public class CreateEntry implements android.os.Parcelable {
+ public final class CreateEntry implements android.os.Parcelable {
ctor public CreateEntry(@NonNull android.app.slice.Slice);
method public int describeContents();
method @NonNull public android.app.slice.Slice getSlice();
@@ -40701,7 +40702,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CreateEntry> CREATOR;
}
- public class CredentialEntry implements android.os.Parcelable {
+ public final class CredentialEntry implements android.os.Parcelable {
ctor public CredentialEntry(@NonNull String, @NonNull String, @NonNull android.app.slice.Slice);
ctor public CredentialEntry(@NonNull android.service.credentials.BeginGetCredentialOption, @NonNull android.app.slice.Slice);
ctor public CredentialEntry(@NonNull String, @NonNull android.app.slice.Slice);
@@ -40741,7 +40742,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialRequest> CREATOR;
}
- public class RemoteEntry implements android.os.Parcelable {
+ public final class RemoteEntry implements android.os.Parcelable {
ctor public RemoteEntry(@NonNull android.app.slice.Slice);
method public int describeContents();
method @NonNull public android.app.slice.Slice getSlice();
@@ -54327,7 +54328,6 @@
method public android.view.accessibility.AccessibilityWindowInfo getWindow();
method public int getWindowId();
method public boolean hasRequestInitialAccessibilityFocus();
- method public boolean hasRequestTouchPassthrough();
method public boolean isAccessibilityDataSensitive();
method public boolean isAccessibilityFocused();
method public boolean isCheckable();
@@ -54411,7 +54411,6 @@
method public void setQueryFromAppProcessEnabled(@NonNull android.view.View, boolean);
method public void setRangeInfo(android.view.accessibility.AccessibilityNodeInfo.RangeInfo);
method public void setRequestInitialAccessibilityFocus(boolean);
- method public void setRequestTouchPassthrough(boolean);
method public void setScreenReaderFocusable(boolean);
method public void setScrollable(boolean);
method public void setSelected(boolean);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 51863bb..7107bf7 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2251,7 +2251,7 @@
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle getBootUser();
- method public int getDisplayIdAssignedToUser();
+ method public int getMainDisplayIdAssignedToUser();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.Set<java.lang.String> getPreInstallableSystemPackages(@NonNull String);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index d0ce701..12026aa 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -72,6 +72,20 @@
private static long sBackgroundPauseDelay = 1000;
/**
+ * A cache of the values in a list. Used so that when calling the list, we have a copy
+ * of it in case the list is modified while iterating. The array can be reused to avoid
+ * allocation on every notification.
+ */
+ private Object[] mCachedList;
+
+ /**
+ * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
+ * complex to keep track of since we notify listeners at different times depending on
+ * startDelay and whether start() was called before end().
+ */
+ boolean mStartListenersCalled = false;
+
+ /**
* Sets the duration for delaying pausing animators when apps go into the background.
* Used by AnimationHandler when requested to pause animators.
*
@@ -158,16 +172,11 @@
* @see AnimatorPauseListener
*/
public void pause() {
- if (isStarted() && !mPaused) {
+ // We only want to pause started Animators or animators that setCurrentPlayTime()
+ // have been called on. mStartListenerCalled will be true if seek has happened.
+ if ((isStarted() || mStartListenersCalled) && !mPaused) {
mPaused = true;
- if (mPauseListeners != null) {
- ArrayList<AnimatorPauseListener> tmpListeners =
- (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationPause(this);
- }
- }
+ notifyPauseListeners(AnimatorCaller.ON_PAUSE);
}
}
@@ -184,14 +193,7 @@
public void resume() {
if (mPaused) {
mPaused = false;
- if (mPauseListeners != null) {
- ArrayList<AnimatorPauseListener> tmpListeners =
- (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationResume(this);
- }
- }
+ notifyPauseListeners(AnimatorCaller.ON_RESUME);
}
}
@@ -450,6 +452,8 @@
if (mPauseListeners != null) {
anim.mPauseListeners = new ArrayList<AnimatorPauseListener>(mPauseListeners);
}
+ anim.mCachedList = null;
+ anim.mStartListenersCalled = false;
return anim;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
@@ -591,6 +595,86 @@
}
/**
+ * Calls notification for each AnimatorListener.
+ *
+ * @param notification The notification method to call on each listener.
+ * @param isReverse When this is used with start/end, this is the isReverse parameter. For
+ * other calls, this is ignored.
+ */
+ void notifyListeners(
+ AnimatorCaller<AnimatorListener, Animator> notification,
+ boolean isReverse
+ ) {
+ callOnList(mListeners, notification, this, isReverse);
+ }
+
+ /**
+ * Call pause/resume on each AnimatorPauseListener.
+ *
+ * @param notification Either ON_PAUSE or ON_RESUME to call onPause or onResume on each
+ * listener.
+ */
+ void notifyPauseListeners(AnimatorCaller<AnimatorPauseListener, Animator> notification) {
+ callOnList(mPauseListeners, notification, this, false);
+ }
+
+ void notifyStartListeners(boolean isReversing) {
+ boolean startListenersCalled = mStartListenersCalled;
+ mStartListenersCalled = true;
+ if (mListeners != null && !startListenersCalled) {
+ notifyListeners(AnimatorCaller.ON_START, isReversing);
+ }
+ }
+
+ void notifyEndListeners(boolean isReversing) {
+ boolean startListenersCalled = mStartListenersCalled;
+ mStartListenersCalled = false;
+ if (mListeners != null && startListenersCalled) {
+ notifyListeners(AnimatorCaller.ON_END, isReversing);
+ }
+ }
+
+ /**
+ * Calls <code>call</code> for every item in <code>list</code> with <code>animator</code> and
+ * <code>isReverse</code> as parameters.
+ *
+ * @param list The list of items to make calls on.
+ * @param call The method to call for each item in list.
+ * @param animator The animator parameter of call.
+ * @param isReverse The isReverse parameter of call.
+ * @param <T> The item type of list
+ * @param <A> The Animator type of animator.
+ */
+ <T, A> void callOnList(
+ ArrayList<T> list,
+ AnimatorCaller<T, A> call,
+ A animator,
+ boolean isReverse
+ ) {
+ int size = list == null ? 0 : list.size();
+ if (size > 0) {
+ // Try to reuse mCacheList to store the items of list.
+ Object[] array;
+ if (mCachedList == null || mCachedList.length < size) {
+ array = new Object[size];
+ } else {
+ array = mCachedList;
+ // Clear it in case there is some reentrancy
+ mCachedList = null;
+ }
+ list.toArray(array);
+ for (int i = 0; i < size; i++) {
+ //noinspection unchecked
+ T item = (T) array[i];
+ call.call(item, animator, isReverse);
+ array[i] = null;
+ }
+ // Store it for the next call so we can reuse this array, if needed.
+ mCachedList = array;
+ }
+ }
+
+ /**
* <p>An animation listener receives notifications from an animation.
* Notifications indicate animation related events, such as the end or the
* repetition of the animation.</p>
@@ -748,4 +832,29 @@
return clone;
}
}
+
+ /**
+ * Internally used by {@link #callOnList(ArrayList, AnimatorCaller, Object, boolean)} to
+ * make a call on all children of a list. This can be for start, stop, pause, cancel, update,
+ * etc notifications.
+ *
+ * @param <T> The type of listener to make the call on
+ * @param <A> The type of animator that is passed as a parameter
+ */
+ interface AnimatorCaller<T, A> {
+ void call(T listener, A animator, boolean isReverse);
+
+ AnimatorCaller<AnimatorListener, Animator> ON_START = AnimatorListener::onAnimationStart;
+ AnimatorCaller<AnimatorListener, Animator> ON_END = AnimatorListener::onAnimationEnd;
+ AnimatorCaller<AnimatorListener, Animator> ON_CANCEL =
+ (listener, animator, isReverse) -> listener.onAnimationCancel(animator);
+ AnimatorCaller<AnimatorListener, Animator> ON_REPEAT =
+ (listener, animator, isReverse) -> listener.onAnimationRepeat(animator);
+ AnimatorCaller<AnimatorPauseListener, Animator> ON_PAUSE =
+ (listener, animator, isReverse) -> listener.onAnimationPause(animator);
+ AnimatorCaller<AnimatorPauseListener, Animator> ON_RESUME =
+ (listener, animator, isReverse) -> listener.onAnimationResume(animator);
+ AnimatorCaller<ValueAnimator.AnimatorUpdateListener, ValueAnimator> ON_UPDATE =
+ (listener, animator, isReverse) -> listener.onAnimationUpdate(animator);
+ }
}
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 257adfe..60659dc 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -32,6 +32,7 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+import java.util.function.Consumer;
/**
* This class plays a set of {@link Animator} objects in the specified order. Animations
@@ -188,11 +189,6 @@
*/
private long[] mChildStartAndStopTimes;
- /**
- * Tracks whether we've notified listeners of the onAnimationStart() event.
- */
- private boolean mStartListenersCalled;
-
// This is to work around a bug in b/34736819. This needs to be removed once app team
// fixes their side.
private AnimatorListenerAdapter mAnimationEndListener = new AnimatorListenerAdapter() {
@@ -423,25 +419,29 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
- if (isStarted()) {
- ArrayList<AnimatorListener> tmpListeners = null;
- if (mListeners != null) {
- tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
- int size = tmpListeners.size();
- for (int i = 0; i < size; i++) {
- tmpListeners.get(i).onAnimationCancel(this);
- }
- }
- ArrayList<Node> playingSet = new ArrayList<>(mPlayingSet);
- int setSize = playingSet.size();
- for (int i = 0; i < setSize; i++) {
- playingSet.get(i).mAnimation.cancel();
- }
+ if (isStarted() || mStartListenersCalled) {
+ notifyListeners(AnimatorCaller.ON_CANCEL, false);
+ callOnPlayingSet(Animator::cancel);
mPlayingSet.clear();
endAnimation();
}
}
+ /**
+ * Calls consumer on every Animator of mPlayingSet.
+ *
+ * @param consumer The method to call on every Animator of mPlayingSet.
+ */
+ private void callOnPlayingSet(Consumer<Animator> consumer) {
+ final ArrayList<Node> list = mPlayingSet;
+ final int size = list.size();
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < size; i++) {
+ final Animator animator = list.get(i).mAnimation;
+ consumer.accept(animator);
+ }
+ }
+
// Force all the animations to end when the duration scale is 0.
private void forceToEnd() {
if (mEndCanBeCalled) {
@@ -481,13 +481,13 @@
return;
}
if (isStarted()) {
+ mStarted = false; // don't allow reentrancy
// Iterate the animations that haven't finished or haven't started, and end them.
if (mReversing) {
// Between start() and first frame, mLastEventId would be unset (i.e. -1)
mLastEventId = mLastEventId == -1 ? mEvents.size() : mLastEventId;
- while (mLastEventId > 0) {
- mLastEventId = mLastEventId - 1;
- AnimationEvent event = mEvents.get(mLastEventId);
+ for (int eventId = mLastEventId - 1; eventId >= 0; eventId--) {
+ AnimationEvent event = mEvents.get(eventId);
Animator anim = event.mNode.mAnimation;
if (mNodeMap.get(anim).mEnded) {
continue;
@@ -503,11 +503,10 @@
}
}
} else {
- while (mLastEventId < mEvents.size() - 1) {
+ for (int eventId = mLastEventId + 1; eventId < mEvents.size(); eventId++) {
// Avoid potential reentrant loop caused by child animators manipulating
// AnimatorSet's lifecycle (i.e. not a recommended approach).
- mLastEventId = mLastEventId + 1;
- AnimationEvent event = mEvents.get(mLastEventId);
+ AnimationEvent event = mEvents.get(eventId);
Animator anim = event.mNode.mAnimation;
if (mNodeMap.get(anim).mEnded) {
continue;
@@ -522,7 +521,6 @@
}
}
}
- mPlayingSet.clear();
}
endAnimation();
}
@@ -662,6 +660,7 @@
super.pause();
if (!previouslyPaused && mPaused) {
mPauseTime = -1;
+ callOnPlayingSet(Animator::pause);
}
}
@@ -676,6 +675,7 @@
if (mPauseTime >= 0) {
addAnimationCallback(0);
}
+ callOnPlayingSet(Animator::resume);
}
}
@@ -716,6 +716,10 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+ if (inReverse == mReversing && selfPulse == mSelfPulse && mStarted) {
+ // It is already started
+ return;
+ }
mStarted = true;
mSelfPulse = selfPulse;
mPaused = false;
@@ -749,32 +753,6 @@
}
}
- private void notifyStartListeners(boolean inReverse) {
- if (mListeners != null && !mStartListenersCalled) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- AnimatorListener listener = tmpListeners.get(i);
- listener.onAnimationStart(this, inReverse);
- }
- }
- mStartListenersCalled = true;
- }
-
- private void notifyEndListeners(boolean inReverse) {
- if (mListeners != null && mStartListenersCalled) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- AnimatorListener listener = tmpListeners.get(i);
- listener.onAnimationEnd(this, inReverse);
- }
- }
- mStartListenersCalled = false;
- }
-
// Returns true if set is empty or contains nothing but animator sets with no start delay.
private static boolean isEmptySet(AnimatorSet set) {
if (set.getStartDelay() > 0) {
@@ -941,12 +919,18 @@
lastPlayTime - node.mStartTime,
notify
);
+ if (notify) {
+ mPlayingSet.remove(node);
+ }
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
);
+ if (notify && !mPlayingSet.contains(node)) {
+ mPlayingSet.add(node);
+ }
}
}
}
@@ -974,12 +958,18 @@
lastPlayTime - node.mStartTime,
notify
);
+ if (notify) {
+ mPlayingSet.remove(node);
+ }
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
);
+ if (notify && !mPlayingSet.contains(node)) {
+ mPlayingSet.add(node);
+ }
}
}
}
@@ -1120,8 +1110,8 @@
mSeekState.setPlayTime(0, mReversing);
}
}
- animateBasedOnPlayTime(playTime, lastPlayTime, mReversing, true);
mSeekState.setPlayTime(playTime, mReversing);
+ animateBasedOnPlayTime(playTime, lastPlayTime, mReversing, true);
}
/**
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 7009725..5d69f8b 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -199,13 +199,6 @@
private boolean mStarted = false;
/**
- * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
- * complex to keep track of since we notify listeners at different times depending on
- * startDelay and whether start() was called before end().
- */
- private boolean mStartListenersCalled = false;
-
- /**
* Flag that denotes whether the animation is set up and ready to go. Used to
* set up animation that has not yet been started.
*/
@@ -1108,30 +1101,6 @@
}
}
- private void notifyStartListeners(boolean isReversing) {
- if (mListeners != null && !mStartListenersCalled) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationStart(this, isReversing);
- }
- }
- mStartListenersCalled = true;
- }
-
- private void notifyEndListeners(boolean isReversing) {
- if (mListeners != null && mStartListenersCalled) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- int numListeners = tmpListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- tmpListeners.get(i).onAnimationEnd(this, isReversing);
- }
- }
- mStartListenersCalled = false;
- }
-
/**
* Start the animation playing. This version of start() takes a boolean flag that indicates
* whether the animation should play in reverse. The flag is usually false, but may be set
@@ -1149,6 +1118,10 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+ if (playBackwards == mResumed && mSelfPulse == !mSuppressSelfPulseRequested && mStarted) {
+ // already started
+ return;
+ }
mReversing = playBackwards;
mSelfPulse = !mSuppressSelfPulseRequested;
// Special case: reversing from seek-to-0 should act as if not seeked at all.
@@ -1219,23 +1192,14 @@
// Only cancel if the animation is actually running or has been started and is about
// to run
// Only notify listeners if the animator has actually started
- if ((mStarted || mRunning) && mListeners != null) {
+ if ((mStarted || mRunning || mStartListenersCalled) && mListeners != null) {
if (!mRunning) {
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners(mReversing);
}
- int listenersSize = mListeners.size();
- if (listenersSize > 0) {
- ArrayList<AnimatorListener> tmpListeners =
- (ArrayList<AnimatorListener>) mListeners.clone();
- for (int i = 0; i < listenersSize; i++) {
- AnimatorListener listener = tmpListeners.get(i);
- listener.onAnimationCancel(this);
- }
- }
+ notifyListeners(AnimatorCaller.ON_CANCEL, false);
}
endAnimation();
-
}
@Override
@@ -1338,11 +1302,11 @@
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners(mReversing);
}
- mRunning = false;
- mStarted = false;
mLastFrameTime = -1;
mFirstFrameTime = -1;
mStartTime = -1;
+ mRunning = false;
+ mStarted = false;
notifyEndListeners(mReversing);
// mReversing needs to be reset *after* notifying the listeners for the end callbacks.
mReversing = false;
@@ -1435,12 +1399,7 @@
done = true;
} else if (newIteration && !lastIterationFinished) {
// Time to repeat
- if (mListeners != null) {
- int numListeners = mListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- mListeners.get(i).onAnimationRepeat(this);
- }
- }
+ notifyListeners(AnimatorCaller.ON_REPEAT, false);
} else if (lastIterationFinished) {
done = true;
}
@@ -1493,13 +1452,8 @@
iteration = Math.min(iteration, mRepeatCount);
lastIteration = Math.min(lastIteration, mRepeatCount);
- if (iteration != lastIteration) {
- if (mListeners != null) {
- int numListeners = mListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- mListeners.get(i).onAnimationRepeat(this);
- }
- }
+ if (notify && iteration != lastIteration) {
+ notifyListeners(AnimatorCaller.ON_REPEAT, false);
}
}
@@ -1697,11 +1651,8 @@
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);
}
- if (mUpdateListeners != null) {
- int numListeners = mUpdateListeners.size();
- for (int i = 0; i < numListeners; ++i) {
- mUpdateListeners.get(i).onAnimationUpdate(this);
- }
+ if (mSeekFraction >= 0 || mStartListenersCalled) {
+ callOnList(mUpdateListeners, AnimatorCaller.ON_UPDATE, this, false);
}
}
@@ -1718,7 +1669,6 @@
anim.mRunning = false;
anim.mPaused = false;
anim.mResumed = false;
- anim.mStartListenersCalled = false;
anim.mStartTime = -1;
anim.mStartTimeCommitted = false;
anim.mAnimationEndRequested = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 981f140..929c07b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -234,7 +234,7 @@
* Map of callbacks that have registered for {@link UidFrozenStateChanged} events.
* Will be called when a Uid has become frozen or unfrozen.
*/
- final ArrayMap<UidFrozenStateChangedCallback, Executor> mFrozenStateChangedCallbacks =
+ private final ArrayMap<UidFrozenStateChangedCallback, Executor> mFrozenStateChangedCallbacks =
new ArrayMap<>();
private final IUidFrozenStateChangedCallback mFrozenStateChangedCallback =
@@ -284,6 +284,8 @@
public @interface UidFrozenState {}
/**
+ * Notify the client that the frozen states of an array of UIDs have changed.
+ *
* @param uids The UIDs for which the frozen state has changed
* @param frozenStates Frozen state for each UID index, Will be set to
* {@link UidFrozenStateChangedCallback#UID_FROZEN_STATE_FROZEN}
@@ -316,9 +318,11 @@
public void registerUidFrozenStateChangedCallback(
@NonNull Executor executor,
@NonNull UidFrozenStateChangedCallback callback) {
+ Preconditions.checkNotNull(executor, "executor cannot be null");
+ Preconditions.checkNotNull(callback, "callback cannot be null");
synchronized (mFrozenStateChangedCallbacks) {
if (mFrozenStateChangedCallbacks.containsKey(callback)) {
- throw new IllegalArgumentException("Callback already registered: " + callback);
+ throw new IllegalStateException("Callback already registered: " + callback);
}
mFrozenStateChangedCallbacks.put(callback, executor);
if (mFrozenStateChangedCallbacks.size() > 1) {
@@ -344,6 +348,7 @@
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void unregisterUidFrozenStateChangedCallback(
@NonNull UidFrozenStateChangedCallback callback) {
+ Preconditions.checkNotNull(callback, "callback cannot be null");
synchronized (mFrozenStateChangedCallbacks) {
mFrozenStateChangedCallbacks.remove(callback);
if (mFrozenStateChangedCallbacks.isEmpty()) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index b96f8c9..0293bb5 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -474,6 +474,12 @@
public abstract BackgroundStartPrivileges getBackgroundStartPrivileges(int uid);
public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
+ /**
+ * Returns whether the app is in a state where it is allowed to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ */
+ public abstract boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName);
+
/** @see com.android.server.am.ActivityManagerService#monitor */
public abstract void monitor();
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 2879062..97d4562 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -108,6 +108,15 @@
int getUidProcessState(int uid, in String callingPackage);
@UnsupportedAppUsage
int checkPermission(in String permission, int pid, int uid);
+
+ /** Logs start of an API call to associate with an FGS, used for FGS Type Metrics */
+ void logFgsApiBegin(int apiType, int appUid, int appPid);
+
+ /** Logs stop of an API call to associate with an FGS, used for FGS Type Metrics */
+ void logFgsApiEnd(int apiType, int appUid, int appPid);
+
+ /** Logs API state change to associate with an FGS, used for FGS Type Metrics */
+ void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);
// =============== End of transactions used on native side as well ============================
// Special low-level communication with activity manager.
@@ -870,15 +879,7 @@
/** Returns if the service is a short-service is still "alive" and past the timeout. */
boolean shouldServiceTimeOut(in ComponentName className, in IBinder token);
- /** Logs start of an API call to associate with an FGS, used for FGS Type Metrics */
- void logFgsApiBegin(int apiType, int appUid, int appPid);
-
- /** Logs stop of an API call to associate with an FGS, used for FGS Type Metrics */
- void logFgsApiEnd(int apiType, int appUid, int appPid);
-
- /** Logs API state change to associate with an FGS, used for FGS Type Metrics */
- void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);
-
void registerUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)")
void unregisterUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ac92811..c131ce5 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -28,6 +28,7 @@
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -1130,7 +1131,7 @@
newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM);
setDisplayIfNeeded(newEvent);
- InputManager.getInstance().injectInputEvent(newEvent,
+ InputManagerGlobal.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
@@ -1151,7 +1152,7 @@
}
UserManager userManager = mInstrContext.getSystemService(UserManager.class);
- int userDisplayId = userManager.getDisplayIdAssignedToUser();
+ int userDisplayId = userManager.getMainDisplayIdAssignedToUser();
if (VERBOSE) {
Log.v(TAG, "setDisplayIfNeeded(" + event + "): eventDisplayId=" + eventDisplayId
+ ", user=" + mInstrContext.getUser() + ", userDisplayId=" + userDisplayId);
@@ -1229,7 +1230,7 @@
}
// Direct the injected event into windows owned by the instrumentation target.
- InputManager.getInstance().injectInputEvent(
+ InputManagerGlobal.getInstance().injectInputEvent(
event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH, Process.myUid());
if (syncAfter) {
@@ -1259,7 +1260,7 @@
if (!event.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) {
event.setSource(InputDevice.SOURCE_TRACKBALL);
}
- InputManager.getInstance().injectInputEvent(event,
+ InputManagerGlobal.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 99de724..cc9c329 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5754,8 +5754,8 @@
private boolean isSnoozeSettingEnabled() {
try {
- return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1;
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0, UserHandle.USER_CURRENT) == 1;
} catch (SecurityException ex) {
// Most 3p apps can't access this snooze setting, so their NotificationListeners
// would be unable to create notification views if we propagated this exception.
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 0bdc222..1df8602 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -42,10 +42,10 @@
},
{
"file_patterns": ["(/|^)AppOpsManager.java"],
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
},
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 404f94a..cdd4b25 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -49,6 +49,12 @@
private static final String TAG = "TaskInfo";
/**
+ * The value to use when the property has not a specific value.
+ * @hide
+ */
+ public static final int PROPERTY_VALUE_UNSET = -1;
+
+ /**
* The id of the user the task was running as if this is a leaf task. The id of the current
* running user of the system otherwise.
* @hide
@@ -230,6 +236,40 @@
public boolean topActivityEligibleForLetterboxEducation;
/**
+ * Whether the double tap is enabled
+ * @hide
+ */
+ public boolean isLetterboxDoubleTapEnabled;
+
+ /**
+ * If {@link isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position or
+ * {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise.
+ * @hide
+ */
+ public int topActivityLetterboxVerticalPosition;
+
+ /**
+ * If {@link isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position or
+ * {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise.
+ * @hide
+ */
+ public int topActivityLetterboxHorizontalPosition;
+
+ /**
+ * If {@link isLetterboxDoubleTapEnabled} it contains the current width of the letterboxed
+ * activity or {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise
+ * @hide
+ */
+ public int topActivityLetterboxWidth;
+
+ /**
+ * If {@link isLetterboxDoubleTapEnabled} it contains the current height of the letterboxed
+ * activity or {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise
+ * @hide
+ */
+ public int topActivityLetterboxHeight;
+
+ /**
* Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
* supports), this is what the system actually uses for resizability based on other policy and
* developer options.
@@ -407,7 +447,8 @@
/** @hide */
public boolean hasCompatUI() {
return hasCameraCompatControl() || topActivityInSizeCompat
- || topActivityEligibleForLetterboxEducation;
+ || topActivityEligibleForLetterboxEducation
+ || isLetterboxDoubleTapEnabled;
}
/**
@@ -456,6 +497,12 @@
&& isResizeable == that.isResizeable
&& supportsMultiWindow == that.supportsMultiWindow
&& displayAreaFeatureId == that.displayAreaFeatureId
+ && isLetterboxDoubleTapEnabled == that.isLetterboxDoubleTapEnabled
+ && topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition
+ && topActivityLetterboxWidth == that.topActivityLetterboxWidth
+ && topActivityLetterboxHeight == that.topActivityLetterboxHeight
+ && topActivityLetterboxHorizontalPosition
+ == that.topActivityLetterboxHorizontalPosition
&& Objects.equals(positionInParent, that.positionInParent)
&& Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
&& Objects.equals(shouldDockBigOverlays, that.shouldDockBigOverlays)
@@ -484,6 +531,12 @@
&& topActivityInSizeCompat == that.topActivityInSizeCompat
&& topActivityEligibleForLetterboxEducation
== that.topActivityEligibleForLetterboxEducation
+ && isLetterboxDoubleTapEnabled == that.isLetterboxDoubleTapEnabled
+ && topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition
+ && topActivityLetterboxHorizontalPosition
+ == that.topActivityLetterboxHorizontalPosition
+ && topActivityLetterboxWidth == that.topActivityLetterboxWidth
+ && topActivityLetterboxHeight == that.topActivityLetterboxHeight
&& cameraCompatControlState == that.cameraCompatControlState
// Bounds are important if top activity has compat controls.
&& (!hasCompatUI() || configuration.windowConfiguration.getBounds()
@@ -538,6 +591,11 @@
mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
displayAreaFeatureId = source.readInt();
cameraCompatControlState = source.readInt();
+ isLetterboxDoubleTapEnabled = source.readBoolean();
+ topActivityLetterboxVerticalPosition = source.readInt();
+ topActivityLetterboxHorizontalPosition = source.readInt();
+ topActivityLetterboxWidth = source.readInt();
+ topActivityLetterboxHeight = source.readInt();
}
/**
@@ -585,6 +643,11 @@
dest.writeTypedObject(mTopActivityLocusId, flags);
dest.writeInt(displayAreaFeatureId);
dest.writeInt(cameraCompatControlState);
+ dest.writeBoolean(isLetterboxDoubleTapEnabled);
+ dest.writeInt(topActivityLetterboxVerticalPosition);
+ dest.writeInt(topActivityLetterboxHorizontalPosition);
+ dest.writeInt(topActivityLetterboxWidth);
+ dest.writeInt(topActivityLetterboxHeight);
}
@Override
@@ -620,6 +683,12 @@
+ " topActivityInSizeCompat=" + topActivityInSizeCompat
+ " topActivityEligibleForLetterboxEducation= "
+ topActivityEligibleForLetterboxEducation
+ + " topActivityLetterboxed= " + isLetterboxDoubleTapEnabled
+ + " topActivityLetterboxVerticalPosition= " + topActivityLetterboxVerticalPosition
+ + " topActivityLetterboxHorizontalPosition= "
+ + topActivityLetterboxHorizontalPosition
+ + " topActivityLetterboxWidth=" + topActivityLetterboxWidth
+ + " topActivityLetterboxHeight=" + topActivityLetterboxHeight
+ " locusId=" + mTopActivityLocusId
+ " displayAreaFeatureId=" + displayAreaFeatureId
+ " cameraCompatControlState="
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d2dbd64..31c02b8 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -302,10 +302,11 @@
@Override
public String getType(AttributionSource attributionSource, Uri uri) {
- // getCallingPackage() isn't available in getType(), as the javadoc states.
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
traceBegin(TRACE_TAG_DATABASE, "getType: ", uri.getAuthority());
+ final AttributionSource original = setCallingAttributionSource(
+ attributionSource);
try {
if (checkGetTypePermission(attributionSource, uri)
== PermissionChecker.PERMISSION_GRANTED) {
@@ -346,6 +347,7 @@
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
} finally {
+ setCallingAttributionSource(original);
Trace.traceEnd(TRACE_TAG_DATABASE);
}
}
@@ -405,16 +407,20 @@
@Override
public void getTypeAnonymousAsync(Uri uri, RemoteCallback callback) {
+ // getCallingPackage() isn't available in getTypeAnonymous(), as the javadoc states.
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
+ traceBegin(TRACE_TAG_DATABASE, "getTypeAnonymous: ", uri.getAuthority());
final Bundle result = new Bundle();
try {
result.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getTypeAnonymous(uri));
} catch (Exception e) {
result.putParcelable(ContentResolver.REMOTE_CALLBACK_ERROR,
new ParcelableException(e));
+ } finally {
+ callback.sendResult(result);
+ Trace.traceEnd(TRACE_TAG_DATABASE);
}
- callback.sendResult(result);
}
@Override
@@ -629,16 +635,19 @@
}
@Override
- public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
- // getCallingPackage() isn't available in getType(), as the javadoc states.
+ public String[] getStreamTypes(AttributionSource attributionSource,
+ Uri uri, String mimeTypeFilter) {
uri = validateIncomingUri(uri);
uri = maybeGetUriWithoutUserId(uri);
traceBegin(TRACE_TAG_DATABASE, "getStreamTypes: ", uri.getAuthority());
+ final AttributionSource original = setCallingAttributionSource(
+ attributionSource);
try {
return mInterface.getStreamTypes(uri, mimeTypeFilter);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
} finally {
+ setCallingAttributionSource(original);
Trace.traceEnd(TRACE_TAG_DATABASE);
}
}
@@ -1114,7 +1123,10 @@
* currently processing a request.
* <p>
* This will always return {@code null} when processing
- * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+ * {@link #getTypeAnonymous(Uri)} requests
+ *
+ * For {@link #getType(Uri)} requests, this will be only available for cases, where
+ * the caller can be identified. See {@link #getTypeAnonymous(Uri)}
*
* @see Binder#getCallingUid()
* @see Context#grantUriPermission(String, Uri, int)
@@ -1154,7 +1166,10 @@
* a request of the request is for the default attribution.
* <p>
* This will always return {@code null} when processing
- * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+ * {@link #getTypeAnonymous(Uri)} requests
+ *
+ * For {@link #getType(Uri)} requests, this will be only available for cases, where
+ * the caller can be identified. See {@link #getTypeAnonymous(Uri)}
*
* @see #getCallingPackage
*/
@@ -1181,7 +1196,10 @@
* {@code null} if not currently processing a request.
* <p>
* This will always return {@code null} when processing
- * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+ * {@link #getTypeAnonymous(Uri)} requests
+ *
+ * For {@link #getType(Uri)} requests, this will be only available for cases, where
+ * the caller can be identified. See {@link #getTypeAnonymous(Uri)}
*
* @see Binder#getCallingUid()
* @see Context#grantUriPermission(String, Uri, int)
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index cc3c012..6b6ac03 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -217,7 +217,7 @@
beforeRemote();
try {
- return mContentProvider.getType(url);
+ return mContentProvider.getType(mAttributionSource, url);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
@@ -237,7 +237,7 @@
beforeRemote();
try {
- return mContentProvider.getStreamTypes(url, mimeTypeFilter);
+ return mContentProvider.getStreamTypes(mAttributionSource, url, mimeTypeFilter);
} catch (DeadObjectException e) {
if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 4ba3ff4..fda3e37 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -315,9 +315,11 @@
case GET_STREAM_TYPES_TRANSACTION:
{
data.enforceInterface(IContentProvider.descriptor);
+ AttributionSource attributionSource = AttributionSource.CREATOR
+ .createFromParcel(data);
Uri url = Uri.CREATOR.createFromParcel(data);
String mimeTypeFilter = data.readString();
- String[] types = getStreamTypes(url, mimeTypeFilter);
+ String[] types = getStreamTypes(attributionSource, url, mimeTypeFilter);
reply.writeNoException();
reply.writeStringArray(types);
@@ -769,12 +771,14 @@
}
@Override
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException
+ public String[] getStreamTypes(AttributionSource attributionSource,
+ Uri url, String mimeTypeFilter) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
data.writeInterfaceToken(IContentProvider.descriptor);
+ attributionSource.writeToParcel(data, 0);
url.writeToParcel(data, 0);
data.writeString(mimeTypeFilter);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 456d218..feca7a0 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1069,7 +1069,7 @@
}
try {
- return provider.getStreamTypes(url, mimeTypeFilter);
+ return provider.getStreamTypes(mContext.getAttributionSource(), url, mimeTypeFilter);
} catch (RemoteException e) {
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index eb80148..ef8d0f9 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -182,8 +182,19 @@
public boolean refresh(@NonNull AttributionSource attributionSource, Uri url,
@Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException;
+ /**
+ * @deprecated -- use getStreamTypes with AttributionSource
+ */
+ @Deprecated
+ default String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+ return getStreamTypes(new AttributionSource(Binder.getCallingUid(),
+ AppGlobals.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0],
+ null), url, mimeTypeFilter);
+ }
+
// Data interchange.
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
+ String[] getStreamTypes(AttributionSource attributionSource,
+ Uri url, String mimeTypeFilter) throws RemoteException;
public AssetFileDescriptor openTypedAssetFile(@NonNull AttributionSource attributionSource,
Uri url, String mimeType, Bundle opts, ICancellationSignal signal)
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index eb14cc4..8aa9b73 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1087,6 +1087,20 @@
254631730L; // buganizer id
/**
+ * This change id enables compat policy that ignores app requested orientation in
+ * response to an app calling {@link android.app.Activity#setRequestedOrientation} more
+ * than twice in one second if an activity is not letterboxed for fixed orientation.
+ * See com.android.server.wm.LetterboxUiController#shouldIgnoreRequestedOrientation
+ * for details.
+ * @hide
+ */
+ @ChangeId
+ @Overridable
+ @Disabled
+ public static final long OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED =
+ 273509367L; // buganizer id
+
+ /**
* This change id forces the packages it is applied to never have Display API sandboxing
* applied for a letterbox or SCM activity. The Display APIs will continue to provide
* DisplayArea bounds.
diff --git a/core/java/android/content/pm/InstallSourceInfo.java b/core/java/android/content/pm/InstallSourceInfo.java
index 67123e8..006d7cd 100644
--- a/core/java/android/content/pm/InstallSourceInfo.java
+++ b/core/java/android/content/pm/InstallSourceInfo.java
@@ -95,8 +95,8 @@
* remains unchanged. It continues to identify the actual package that performed the install
* or update.
* <p>
- * Null may be returned if the app was not installed by a package (e.g. a system app or an app
- * installed via adb) or if the initiating package has itself been uninstalled.
+ * Null may be returned if the app was not installed by a package (e.g. a system app) or if the
+ * initiating package has itself been uninstalled.
*/
@Nullable
public String getInitiatingPackageName() {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b9c671a..21e2a13 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -10134,25 +10134,9 @@
/**
* Register an application dex module with the package manager.
- * The package manager will keep track of the given module for future optimizations.
*
- * Dex module optimizations will disable the classpath checking at runtime. The client bares
- * the responsibility to ensure that the static assumptions on classes in the optimized code
- * hold at runtime (e.g. there's no duplicate classes in the classpath).
- *
- * Note that the package manager already keeps track of dex modules loaded with
- * {@link dalvik.system.DexClassLoader} and {@link dalvik.system.PathClassLoader}.
- * This can be called for an eager registration.
- *
- * The call might take a while and the results will be posted on the main thread, using
- * the given callback.
- *
- * If the module is intended to be shared with other apps, make sure that the file
- * permissions allow for it.
- * If at registration time the permissions allow for others to read it, the module would
- * be marked as a shared module which might undergo a different optimization strategy.
- * (usually shared modules will generated larger optimizations artifacts,
- * taking more disk space).
+ * This call no longer does anything. If a callback is given it is called with a false success
+ * value.
*
* @param dexModulePath the absolute path of the dex module.
* @param callback if not null, {@link DexModuleRegisterCallback#onDexModuleRegistered} will
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 493a4ff..5579d22 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -16,8 +16,6 @@
package android.credentials;
-import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;
-
import static java.util.Objects.requireNonNull;
import android.annotation.CallbackExecutor;
@@ -167,37 +165,83 @@
}
/**
- * Gets a {@link GetPendingCredentialResponse} that can launch the credential retrieval UI flow
- * to request a user credential for your app.
+ * Launches the remaining flows to retrieve an app credential from the user, after the
+ * completed prefetch work corresponding to the given {@code pendingGetCredentialHandle}.
+ *
+ * <p>The execution can potentially launch UI flows to collect user consent to using a
+ * credential, display a picker when multiple credentials exist, etc.
+ *
+ * <p>Use this API to complete the full credential retrieval operation after you initiated a
+ * request through the {@link #prepareGetCredential(
+ * GetCredentialRequest, CancellationSignal, Executor, OutcomeReceiver)} API.
+ *
+ * @param pendingGetCredentialHandle the handle representing the pending operation to resume
+ * @param activity the activity used to launch any UI needed
+ * @param cancellationSignal an optional signal that allows for cancelling this call
+ * @param executor the callback will take place on this {@link Executor}
+ * @param callback the callback invoked when the request succeeds or fails
+ */
+ public void getCredential(
+ @NonNull PrepareGetCredentialResponse.PendingGetCredentialHandle
+ pendingGetCredentialHandle,
+ @NonNull Activity activity,
+ @Nullable CancellationSignal cancellationSignal,
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
+ requireNonNull(pendingGetCredentialHandle, "pendingGetCredentialHandle must not be null");
+ requireNonNull(activity, "activity must not be null");
+ requireNonNull(executor, "executor must not be null");
+ requireNonNull(callback, "callback must not be null");
+
+ if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+ Log.w(TAG, "getCredential already canceled");
+ return;
+ }
+
+ pendingGetCredentialHandle.show(activity, cancellationSignal, executor, callback);
+ }
+
+ /**
+ * Prepare for a get-credential operation. Returns a {@link PrepareGetCredentialResponse} that
+ * can launch the credential retrieval UI flow to request a user credential for your app.
+ *
+ * <p>This API doesn't invoke any UI. It only performs the preparation work so that you can
+ * later launch the remaining get-credential operation (involves UIs) through the {@link
+ * #getCredential(PrepareGetCredentialResponse.PendingGetCredentialHandle, Activity,
+ * CancellationSignal, Executor, OutcomeReceiver)} API which incurs less latency compared to
+ * the {@link #getCredential(GetCredentialRequest, Activity, CancellationSignal, Executor,
+ * OutcomeReceiver)} API that executes the whole operation in one call.
*
* @param request the request specifying type(s) of credentials to get from the user
* @param cancellationSignal an optional signal that allows for cancelling this call
* @param executor the callback will take place on this {@link Executor}
* @param callback the callback invoked when the request succeeds or fails
- *
- * @hide
*/
- public void getPendingCredential(
+ public void prepareGetCredential(
@NonNull GetCredentialRequest request,
@Nullable CancellationSignal cancellationSignal,
@CallbackExecutor @NonNull Executor executor,
@NonNull OutcomeReceiver<
- GetPendingCredentialResponse, GetCredentialException> callback) {
+ PrepareGetCredentialResponse, GetCredentialException> callback) {
requireNonNull(request, "request must not be null");
requireNonNull(executor, "executor must not be null");
requireNonNull(callback, "callback must not be null");
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- Log.w(TAG, "getPendingCredential already canceled");
+ Log.w(TAG, "prepareGetCredential already canceled");
return;
}
ICancellationSignal cancelRemote = null;
+ GetCredentialTransportPendingUseCase getCredentialTransport =
+ new GetCredentialTransportPendingUseCase();
try {
cancelRemote =
- mService.executeGetPendingCredential(
+ mService.executePrepareGetCredential(
request,
- new GetPendingCredentialTransport(executor, callback),
+ new PrepareGetCredentialTransport(
+ executor, callback, getCredentialTransport),
+ getCredentialTransport,
mContext.getOpPackageName());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
@@ -484,23 +528,27 @@
}
}
- private static class GetPendingCredentialTransport extends IGetPendingCredentialCallback.Stub {
+ private static class PrepareGetCredentialTransport extends IPrepareGetCredentialCallback.Stub {
// TODO: listen for cancellation to release callback.
private final Executor mExecutor;
private final OutcomeReceiver<
- GetPendingCredentialResponse, GetCredentialException> mCallback;
+ PrepareGetCredentialResponse, GetCredentialException> mCallback;
+ private final GetCredentialTransportPendingUseCase mGetCredentialTransport;
- private GetPendingCredentialTransport(
+ private PrepareGetCredentialTransport(
Executor executor,
- OutcomeReceiver<GetPendingCredentialResponse, GetCredentialException> callback) {
+ OutcomeReceiver<PrepareGetCredentialResponse, GetCredentialException> callback,
+ GetCredentialTransportPendingUseCase getCredentialTransport) {
mExecutor = executor;
mCallback = callback;
+ mGetCredentialTransport = getCredentialTransport;
}
@Override
- public void onResponse(GetPendingCredentialResponse response) {
- mExecutor.execute(() -> mCallback.onResult(response));
+ public void onResponse(PrepareGetCredentialResponseInternal response) {
+ mExecutor.execute(() -> mCallback.onResult(
+ new PrepareGetCredentialResponse(response, mGetCredentialTransport)));
}
@Override
@@ -510,6 +558,51 @@
}
}
+ /** @hide */
+ protected static class GetCredentialTransportPendingUseCase
+ extends IGetCredentialCallback.Stub {
+ @Nullable private PrepareGetCredentialResponse.GetPendingCredentialInternalCallback
+ mCallback = null;
+
+ private GetCredentialTransportPendingUseCase() {}
+
+ public void setCallback(
+ PrepareGetCredentialResponse.GetPendingCredentialInternalCallback callback) {
+ if (mCallback == null) {
+ mCallback = callback;
+ } else {
+ throw new IllegalStateException("callback has already been set once");
+ }
+ }
+
+ @Override
+ public void onPendingIntent(PendingIntent pendingIntent) {
+ if (mCallback != null) {
+ mCallback.onPendingIntent(pendingIntent);
+ } else {
+ Log.d(TAG, "Unexpected onPendingIntent call before the show invocation");
+ }
+ }
+
+ @Override
+ public void onResponse(GetCredentialResponse response) {
+ if (mCallback != null) {
+ mCallback.onResponse(response);
+ } else {
+ Log.d(TAG, "Unexpected onResponse call before the show invocation");
+ }
+ }
+
+ @Override
+ public void onError(String errorType, String message) {
+ if (mCallback != null) {
+ mCallback.onError(errorType, message);
+ } else {
+ Log.d(TAG, "Unexpected onError call before the show invocation");
+ }
+ }
+ }
+
private static class GetCredentialTransport extends IGetCredentialCallback.Stub {
// TODO: listen for cancellation to release callback.
@@ -535,7 +628,8 @@
TAG,
"startIntentSender() failed for intent:" + pendingIntent.getIntentSender(),
e);
- // TODO: propagate the error.
+ mExecutor.execute(() -> mCallback.onError(
+ new GetCredentialException(GetCredentialException.TYPE_UNKNOWN)));
}
}
@@ -577,7 +671,8 @@
TAG,
"startIntentSender() failed for intent:" + pendingIntent.getIntentSender(),
e);
- // TODO: propagate the error.
+ mExecutor.execute(() -> mCallback.onError(
+ new CreateCredentialException(CreateCredentialException.TYPE_UNKNOWN)));
}
}
diff --git a/core/java/android/credentials/GetPendingCredentialResponse.java b/core/java/android/credentials/GetPendingCredentialResponse.java
deleted file mode 100644
index 9005d9d..0000000
--- a/core/java/android/credentials/GetPendingCredentialResponse.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.credentials;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.os.CancellationSignal;
-import android.os.OutcomeReceiver;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.concurrent.Executor;
-
-
-/**
- * A response object that prefetches user app credentials and provides metadata about them. It can
- * then be used to issue the full credential retrieval flow via the
- * {@link #show(Activity, CancellationSignal, Executor, OutcomeReceiver)} method to perform the
- * necessary flows such as consent collection and officially retrieve a credential.
- *
- * @hide
- */
-public final class GetPendingCredentialResponse implements Parcelable {
- private final boolean mHasCredentialResults;
- private final boolean mHasAuthenticationResults;
- private final boolean mHasRemoteResults;
-
- /** Returns true if the user has any candidate credentials, and false otherwise. */
- public boolean hasCredentialResults() {
- return mHasCredentialResults;
- }
-
- /**
- * Returns true if the user has any candidate authentication actions (locked credential
- * supplier), and false otherwise.
- */
- public boolean hasAuthenticationResults() {
- return mHasAuthenticationResults;
- }
-
- /**
- * Returns true if the user has any candidate remote credential results, and false otherwise.
- */
- public boolean hasRemoteResults() {
- return mHasRemoteResults;
- }
-
- /**
- * Launches the necessary flows such as consent collection and credential selection to
- * officially retrieve a credential among the pending credential candidates.
- *
- * @param activity the activity used to launch any UI needed
- * @param cancellationSignal an optional signal that allows for cancelling this call
- * @param executor the callback will take place on this {@link Executor}
- * @param callback the callback invoked when the request succeeds or fails
- */
- public void show(@NonNull Activity activity, @Nullable CancellationSignal cancellationSignal,
- @CallbackExecutor @NonNull Executor executor,
- @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
- // TODO(b/273308895): implement
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeBoolean(mHasCredentialResults);
- dest.writeBoolean(mHasAuthenticationResults);
- dest.writeBoolean(mHasRemoteResults);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public String toString() {
- return "GetCredentialResponse {" + "credential=" + mHasCredentialResults + "}";
- }
-
- /**
- * Constructs a {@link GetPendingCredentialResponse}.
- *
- * @param hasCredentialResults whether the user has any candidate credentials
- * @param hasAuthenticationResults whether the user has any candidate authentication actions
- * @param hasRemoteResults whether the user has any candidate remote options
- */
- public GetPendingCredentialResponse(boolean hasCredentialResults,
- boolean hasAuthenticationResults, boolean hasRemoteResults) {
- mHasCredentialResults = hasCredentialResults;
- mHasAuthenticationResults = hasAuthenticationResults;
- mHasRemoteResults = hasRemoteResults;
- }
-
- private GetPendingCredentialResponse(@NonNull Parcel in) {
- mHasCredentialResults = in.readBoolean();
- mHasAuthenticationResults = in.readBoolean();
- mHasRemoteResults = in.readBoolean();
- }
-
- public static final @NonNull Creator<GetPendingCredentialResponse> CREATOR = new Creator<>() {
- @Override
- public GetPendingCredentialResponse[] newArray(int size) {
- return new GetPendingCredentialResponse[size];
- }
-
- @Override
- public GetPendingCredentialResponse createFromParcel(@NonNull Parcel in) {
- return new GetPendingCredentialResponse(in);
- }
- };
-}
diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl
index af8e7b4..5fde96b 100644
--- a/core/java/android/credentials/ICredentialManager.aidl
+++ b/core/java/android/credentials/ICredentialManager.aidl
@@ -27,7 +27,7 @@
import android.credentials.IClearCredentialStateCallback;
import android.credentials.ICreateCredentialCallback;
import android.credentials.IGetCredentialCallback;
-import android.credentials.IGetPendingCredentialCallback;
+import android.credentials.IPrepareGetCredentialCallback;
import android.credentials.ISetEnabledProvidersCallback;
import android.content.ComponentName;
import android.os.ICancellationSignal;
@@ -41,7 +41,7 @@
@nullable ICancellationSignal executeGetCredential(in GetCredentialRequest request, in IGetCredentialCallback callback, String callingPackage);
- @nullable ICancellationSignal executeGetPendingCredential(in GetCredentialRequest request, in IGetPendingCredentialCallback callback, String callingPackage);
+ @nullable ICancellationSignal executePrepareGetCredential(in GetCredentialRequest request, in IPrepareGetCredentialCallback prepareGetCredentialCallback, in IGetCredentialCallback getCredentialCallback, String callingPackage);
@nullable ICancellationSignal executeCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage);
diff --git a/core/java/android/credentials/IGetPendingCredentialCallback.aidl b/core/java/android/credentials/IPrepareGetCredentialCallback.aidl
similarity index 76%
rename from core/java/android/credentials/IGetPendingCredentialCallback.aidl
rename to core/java/android/credentials/IPrepareGetCredentialCallback.aidl
index 4ab0f99..c918aec 100644
--- a/core/java/android/credentials/IGetPendingCredentialCallback.aidl
+++ b/core/java/android/credentials/IPrepareGetCredentialCallback.aidl
@@ -17,14 +17,14 @@
package android.credentials;
import android.app.PendingIntent;
-import android.credentials.GetPendingCredentialResponse;
+import android.credentials.PrepareGetCredentialResponseInternal;
/**
- * Listener for a executeGetPendingCredential request.
+ * Listener for a executePrepareGetCredential request.
*
* @hide
*/
-interface IGetPendingCredentialCallback {
- oneway void onResponse(in GetPendingCredentialResponse response);
+interface IPrepareGetCredentialCallback {
+ oneway void onResponse(in PrepareGetCredentialResponseInternal response);
oneway void onError(String errorType, String message);
}
\ No newline at end of file
diff --git a/core/java/android/credentials/PrepareGetCredentialResponse.java b/core/java/android/credentials/PrepareGetCredentialResponse.java
new file mode 100644
index 0000000..81e9068
--- /dev/null
+++ b/core/java/android/credentials/PrepareGetCredentialResponse.java
@@ -0,0 +1,180 @@
+/*
+ * 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.credentials;
+
+import static android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.IntentSender;
+import android.os.CancellationSignal;
+import android.os.OutcomeReceiver;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+
+/**
+ * A response object that prefetches user app credentials and provides metadata about them. It can
+ * then be used to issue the full credential retrieval flow via the
+ * {@link CredentialManager#getCredential(PendingGetCredentialHandle, Activity, CancellationSignal,
+ * Executor, OutcomeReceiver)} method to perform the remaining flows such as consent collection
+ * and credential selection, to officially retrieve a credential.
+ */
+public final class PrepareGetCredentialResponse {
+
+ /**
+ * A handle that represents a pending get-credential operation. Pass this handle to {@link
+ * CredentialManager#getCredential(PendingGetCredentialHandle, Activity, CancellationSignal,
+ * Executor, OutcomeReceiver)} to perform the remaining flows to officially retrieve a
+ * credential.
+ */
+ public static final class PendingGetCredentialHandle {
+ @NonNull
+ private final CredentialManager.GetCredentialTransportPendingUseCase
+ mGetCredentialTransport;
+ /**
+ * The pending intent to be launched to finalize the user credential. If null, the callback
+ * will fail with {@link GetCredentialException#TYPE_NO_CREDENTIAL}.
+ */
+ @Nullable
+ private final PendingIntent mPendingIntent;
+
+ /** @hide */
+ PendingGetCredentialHandle(
+ @NonNull CredentialManager.GetCredentialTransportPendingUseCase transport,
+ @Nullable PendingIntent pendingIntent) {
+ mGetCredentialTransport = transport;
+ mPendingIntent = pendingIntent;
+ }
+
+ /** @hide */
+ void show(@NonNull Activity activity, @Nullable CancellationSignal cancellationSignal,
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
+ if (mPendingIntent == null) {
+ executor.execute(() -> callback.onError(
+ new GetCredentialException(GetCredentialException.TYPE_NO_CREDENTIAL)));
+ return;
+ }
+
+ mGetCredentialTransport.setCallback(new GetPendingCredentialInternalCallback() {
+ @Override
+ public void onPendingIntent(PendingIntent pendingIntent) {
+ try {
+ activity.startIntentSender(pendingIntent.getIntentSender(), null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "startIntentSender() failed for intent for show()", e);
+ executor.execute(() -> callback.onError(
+ new GetCredentialException(GetCredentialException.TYPE_UNKNOWN)));
+ }
+ }
+
+ @Override
+ public void onResponse(GetCredentialResponse response) {
+ executor.execute(() -> callback.onResult(response));
+ }
+
+ @Override
+ public void onError(String errorType, String message) {
+ executor.execute(
+ () -> callback.onError(new GetCredentialException(errorType, message)));
+ }
+ });
+
+ try {
+ activity.startIntentSender(mPendingIntent.getIntentSender(), null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "startIntentSender() failed for intent for show()", e);
+ executor.execute(() -> callback.onError(
+ new GetCredentialException(GetCredentialException.TYPE_UNKNOWN)));
+ }
+ }
+ }
+ private static final String TAG = "CredentialManager";
+
+ @NonNull private final PrepareGetCredentialResponseInternal mResponseInternal;
+
+ @NonNull private final PendingGetCredentialHandle mPendingGetCredentialHandle;
+
+ /**
+ * Returns true if the user has any candidate credentials for the given {@code credentialType},
+ * and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasCredentialResults(@NonNull String credentialType) {
+ return mResponseInternal.hasCredentialResults(credentialType);
+ }
+
+ /**
+ * Returns true if the user has any candidate authentication actions (locked credential
+ * supplier), and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasAuthenticationResults() {
+ return mResponseInternal.hasAuthenticationResults();
+ }
+
+ /**
+ * Returns true if the user has any candidate remote credential results, and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasRemoteResults() {
+ return mResponseInternal.hasRemoteResults();
+ }
+
+ /**
+ * Returns a handle that represents this pending get-credential operation. Pass this handle to
+ * {@link CredentialManager#getCredential(PendingGetCredentialHandle, Activity,
+ * CancellationSignal, Executor, OutcomeReceiver)} to perform the remaining flows to officially
+ * retrieve a credential.
+ */
+ @NonNull
+ public PendingGetCredentialHandle getPendingGetCredentialHandle() {
+ return mPendingGetCredentialHandle;
+ }
+
+ /**
+ * Constructs a {@link PrepareGetCredentialResponse}.
+ *
+ * @param responseInternal whether caller has the permission to query the credential
+ * result metadata
+ * @param getCredentialTransport the transport for the operation to finalaze a credential
+ * @hide
+ */
+ protected PrepareGetCredentialResponse(
+ @NonNull PrepareGetCredentialResponseInternal responseInternal,
+ @NonNull CredentialManager.GetCredentialTransportPendingUseCase
+ getCredentialTransport) {
+ mResponseInternal = responseInternal;
+ mPendingGetCredentialHandle = new PendingGetCredentialHandle(
+ getCredentialTransport, responseInternal.getPendingIntent());
+ }
+
+ /** @hide */
+ protected interface GetPendingCredentialInternalCallback {
+ void onPendingIntent(@NonNull PendingIntent pendingIntent);
+
+ void onResponse(@NonNull GetCredentialResponse response);
+
+ void onError(@NonNull String errorType, @Nullable String message);
+ }
+}
diff --git a/core/java/android/credentials/GetPendingCredentialResponse.aidl b/core/java/android/credentials/PrepareGetCredentialResponseInternal.aidl
similarity index 92%
rename from core/java/android/credentials/GetPendingCredentialResponse.aidl
rename to core/java/android/credentials/PrepareGetCredentialResponseInternal.aidl
index 1cdd637..217dac8 100644
--- a/core/java/android/credentials/GetPendingCredentialResponse.aidl
+++ b/core/java/android/credentials/PrepareGetCredentialResponseInternal.aidl
@@ -16,4 +16,4 @@
package android.credentials;
-parcelable GetPendingCredentialResponse;
\ No newline at end of file
+parcelable PrepareGetCredentialResponseInternal;
\ No newline at end of file
diff --git a/core/java/android/credentials/PrepareGetCredentialResponseInternal.java b/core/java/android/credentials/PrepareGetCredentialResponseInternal.java
new file mode 100644
index 0000000..9afd44f
--- /dev/null
+++ b/core/java/android/credentials/PrepareGetCredentialResponseInternal.java
@@ -0,0 +1,167 @@
+/*
+ * 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.credentials;
+
+import static android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.os.CancellationSignal;
+import android.os.OutcomeReceiver;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArraySet;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+
+/**
+ * An internal response object that prefetches user app credentials and provides metadata about
+ * them.
+ *
+ * @hide
+ */
+public final class PrepareGetCredentialResponseInternal implements Parcelable {
+ private static final String TAG = "CredentialManager";
+
+ private final boolean mHasQueryApiPermission;
+ @Nullable
+ private final ArraySet<String> mCredentialResultTypes;
+ private final boolean mHasAuthenticationResults;
+ private final boolean mHasRemoteResults;
+ /**
+ * The pending intent to be launched to finalize the user credential. If null, the callback
+ * will fail with {@link GetCredentialException#TYPE_NO_CREDENTIAL}.
+ */
+ @Nullable
+ private final PendingIntent mPendingIntent;
+
+ @Nullable
+ public PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ /**
+ * Returns true if the user has any candidate credentials for the given {@code credentialType},
+ * and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasCredentialResults(@NonNull String credentialType) {
+ if (!mHasQueryApiPermission) {
+ throw new SecurityException(
+ "caller doesn't have the permission to query credential results");
+ }
+ if (mCredentialResultTypes == null) {
+ return false;
+ }
+ return mCredentialResultTypes.contains(credentialType);
+ }
+
+ /**
+ * Returns true if the user has any candidate authentication actions (locked credential
+ * supplier), and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasAuthenticationResults() {
+ if (!mHasQueryApiPermission) {
+ throw new SecurityException(
+ "caller doesn't have the permission to query authentication results");
+ }
+ return mHasAuthenticationResults;
+ }
+
+ /**
+ * Returns true if the user has any candidate remote credential results, and false otherwise.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+ public boolean hasRemoteResults() {
+ if (!mHasQueryApiPermission) {
+ throw new SecurityException(
+ "caller doesn't have the permission to query remote results");
+ }
+ return mHasRemoteResults;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeBoolean(mHasQueryApiPermission);
+ dest.writeArraySet(mCredentialResultTypes);
+ dest.writeBoolean(mHasAuthenticationResults);
+ dest.writeBoolean(mHasRemoteResults);
+ dest.writeTypedObject(mPendingIntent, flags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Constructs a {@link PrepareGetCredentialResponseInternal}.
+ *
+ * @param hasQueryApiPermission whether caller has the permission to query the credential
+ * result metadata
+ * @param credentialResultTypes a set of credential types that each has candidate credentials
+ * found, or null if the caller doesn't have the permission to
+ * this information
+ * @param hasAuthenticationResults whether the user has any candidate authentication actions, or
+ * false if the caller doesn't have the permission to this
+ * information
+ * @param hasRemoteResults whether the user has any candidate remote options, or false
+ * if the caller doesn't have the permission to this information
+ * @param pendingIntent the pending intent to be launched during
+ * {@link #show(Activity, CancellationSignal, Executor,
+ * OutcomeReceiver)}} to
+ * finalize the user credential
+ * @hide
+ */
+ public PrepareGetCredentialResponseInternal(boolean hasQueryApiPermission,
+ @Nullable Set<String> credentialResultTypes,
+ boolean hasAuthenticationResults, boolean hasRemoteResults,
+ @Nullable PendingIntent pendingIntent) {
+ mHasQueryApiPermission = hasQueryApiPermission;
+ mCredentialResultTypes = new ArraySet<>(credentialResultTypes);
+ mHasAuthenticationResults = hasAuthenticationResults;
+ mHasRemoteResults = hasRemoteResults;
+ mPendingIntent = pendingIntent;
+ }
+
+ private PrepareGetCredentialResponseInternal(@NonNull Parcel in) {
+ mHasQueryApiPermission = in.readBoolean();
+ mCredentialResultTypes = (ArraySet<String>) in.readArraySet(null);
+ mHasAuthenticationResults = in.readBoolean();
+ mHasRemoteResults = in.readBoolean();
+ mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
+ }
+
+ public static final @NonNull Creator<PrepareGetCredentialResponseInternal> CREATOR =
+ new Creator<>() {
+ @Override
+ public PrepareGetCredentialResponseInternal[] newArray(int size) {
+ return new PrepareGetCredentialResponseInternal[size];
+ }
+
+ @Override
+ public PrepareGetCredentialResponseInternal createFromParcel(@NonNull Parcel in) {
+ return new PrepareGetCredentialResponseInternal(in);
+ }
+ };
+}
diff --git a/core/java/android/credentials/ui/RequestInfo.java b/core/java/android/credentials/ui/RequestInfo.java
index 49ae9e9..09d2db8 100644
--- a/core/java/android/credentials/ui/RequestInfo.java
+++ b/core/java/android/credentials/ui/RequestInfo.java
@@ -74,13 +74,30 @@
@NonNull
private final String mAppPackageName;
+ private final boolean mHasPermissionToOverrideDefault;
+
/** Creates new {@code RequestInfo} for a create-credential flow. */
@NonNull
public static RequestInfo newCreateRequestInfo(
@NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
@NonNull String appPackageName) {
return new RequestInfo(
- token, TYPE_CREATE, appPackageName, createCredentialRequest, null);
+ token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
+ /*hasPermissionToOverrideDefault=*/ false);
+ }
+
+ /**
+ * Creates new {@code RequestInfo} for a create-credential flow.
+ *
+ * @hide
+ */
+ @NonNull
+ public static RequestInfo newCreateRequestInfo(
+ @NonNull IBinder token, @NonNull CreateCredentialRequest createCredentialRequest,
+ @NonNull String appPackageName, boolean hasPermissionToOverrideDefault) {
+ return new RequestInfo(
+ token, TYPE_CREATE, appPackageName, createCredentialRequest, null,
+ hasPermissionToOverrideDefault);
}
/** Creates new {@code RequestInfo} for a get-credential flow. */
@@ -89,7 +106,18 @@
@NonNull IBinder token, @NonNull GetCredentialRequest getCredentialRequest,
@NonNull String appPackageName) {
return new RequestInfo(
- token, TYPE_GET, appPackageName, null, getCredentialRequest);
+ token, TYPE_GET, appPackageName, null, getCredentialRequest,
+ /*hasPermissionToOverrideDefault=*/ false);
+ }
+
+
+ /**
+ * Returns whether the calling package has the permission
+ *
+ * @hide
+ */
+ public boolean hasPermissionToOverrideDefault() {
+ return mHasPermissionToOverrideDefault;
}
/** Returns the request token matching the user request. */
@@ -132,12 +160,14 @@
private RequestInfo(@NonNull IBinder token, @NonNull @RequestType String type,
@NonNull String appPackageName,
@Nullable CreateCredentialRequest createCredentialRequest,
- @Nullable GetCredentialRequest getCredentialRequest) {
+ @Nullable GetCredentialRequest getCredentialRequest,
+ boolean hasPermissionToOverrideDefault) {
mToken = token;
mType = type;
mAppPackageName = appPackageName;
mCreateCredentialRequest = createCredentialRequest;
mGetCredentialRequest = getCredentialRequest;
+ mHasPermissionToOverrideDefault = hasPermissionToOverrideDefault;
}
private RequestInfo(@NonNull Parcel in) {
@@ -157,6 +187,7 @@
AnnotationValidations.validate(NonNull.class, null, mAppPackageName);
mCreateCredentialRequest = createCredentialRequest;
mGetCredentialRequest = getCredentialRequest;
+ mHasPermissionToOverrideDefault = in.readBoolean();
}
@Override
@@ -166,6 +197,7 @@
dest.writeString8(mAppPackageName);
dest.writeTypedObject(mCreateCredentialRequest, flags);
dest.writeTypedObject(mGetCredentialRequest, flags);
+ dest.writeBoolean(mHasPermissionToOverrideDefault);
}
@Override
diff --git a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
index 18979a9..bf3df90 100644
--- a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
@@ -23,10 +23,10 @@
* @hide
*/
oneway interface IBiometricContextListener {
- // Called when doze or awake (screen on) status changes.
+ // Called when aod or awake (screen on) status changes.
// These may be called while the device is still transitioning to the new state
// (i.e. about to become awake or enter doze)
- void onDozeChanged(boolean isDozing, boolean isAwake);
+ void onDozeChanged(boolean isAod, boolean isAwake);
@VintfStability
@Backing(type="int")
@@ -39,4 +39,8 @@
// Called when the fold state of the device changes.
void onFoldChanged(FoldState FoldState);
+
+ // Called when the display state of the device changes.
+ // Where `displayState` is defined in AuthenticateOptions.DisplayState
+ void onDisplayStateChanged(int displayState);
}
diff --git a/core/java/android/hardware/display/HdrConversionMode.java b/core/java/android/hardware/display/HdrConversionMode.java
index 49e5eff..5fccb5e 100644
--- a/core/java/android/hardware/display/HdrConversionMode.java
+++ b/core/java/android/hardware/display/HdrConversionMode.java
@@ -29,9 +29,6 @@
/**
* Describes the HDR conversion mode for a device.
*
- * This class is used when user changes the HDR conversion mode of the device via
- * {@link DisplayManager#setHdrConversionMode(HdrConversionMode)}.
- * <p>
* HDR conversion mode has a conversionMode and preferredHdrOutputType. </p><p>
* The conversionMode can be one of:
* {@link HdrConversionMode#HDR_CONVERSION_UNSUPPORTED} : HDR conversion is unsupported. In this
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 3fffb3c..03d6d91 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -161,9 +161,8 @@
}
/**
- * Returns the recording session associated with this VirtualDisplay. Only used for
+ * Returns the recording session associated with this {@link VirtualDisplay}. Only used for
* recording via {@link MediaProjection}.
- *
* @hide
*/
@Nullable
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 5dc3825..8a4a0e4 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -34,12 +34,10 @@
import android.hardware.BatteryState;
import android.hardware.SensorManager;
import android.hardware.lights.LightsManager;
-import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.InputEventInjectionSync;
-import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Vibrator;
@@ -392,12 +390,7 @@
* @hide
*/
public boolean isInputDeviceEnabled(int id) {
- try {
- return mIm.isInputDeviceEnabled(id);
- } catch (RemoteException ex) {
- Log.w(TAG, "Could not check enabled status of input device with id = " + id);
- throw ex.rethrowFromSystemServer();
- }
+ return mGlobal.isInputDeviceEnabled(id);
}
/**
@@ -411,12 +404,7 @@
* @hide
*/
public void enableInputDevice(int id) {
- try {
- mIm.enableInputDevice(id);
- } catch (RemoteException ex) {
- Log.w(TAG, "Could not enable input device with id = " + id);
- throw ex.rethrowFromSystemServer();
- }
+ mGlobal.enableInputDevice(id);
}
/**
@@ -430,12 +418,7 @@
* @hide
*/
public void disableInputDevice(int id) {
- try {
- mIm.disableInputDevice(id);
- } catch (RemoteException ex) {
- Log.w(TAG, "Could not disable input device with id = " + id);
- throw ex.rethrowFromSystemServer();
- }
+ mGlobal.disableInputDevice(id);
}
/**
@@ -1007,13 +990,7 @@
* @hide
*/
public boolean[] deviceHasKeys(int id, int[] keyCodes) {
- boolean[] ret = new boolean[keyCodes.length];
- try {
- mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return ret;
+ return mGlobal.deviceHasKeys(id, keyCodes);
}
/**
@@ -1038,11 +1015,7 @@
* @hide
*/
public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) {
- try {
- return mIm.getKeyCodeForKeyLocation(deviceId, locationKeyCode);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return mGlobal.getKeyCodeForKeyLocation(deviceId, locationKeyCode);
}
/**
@@ -1075,20 +1048,7 @@
*/
@RequiresPermission(Manifest.permission.INJECT_EVENTS)
public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
- if (event == null) {
- throw new IllegalArgumentException("event must not be null");
- }
- if (mode != InputEventInjectionSync.NONE
- && mode != InputEventInjectionSync.WAIT_FOR_FINISHED
- && mode != InputEventInjectionSync.WAIT_FOR_RESULT) {
- throw new IllegalArgumentException("mode is invalid");
- }
-
- try {
- return mIm.injectInputEventToTarget(event, mode, targetUid);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return mGlobal.injectInputEvent(event, mode, targetUid);
}
/**
@@ -1114,7 +1074,7 @@
@RequiresPermission(Manifest.permission.INJECT_EVENTS)
@UnsupportedAppUsage
public boolean injectInputEvent(InputEvent event, int mode) {
- return injectInputEvent(event, mode, Process.INVALID_UID);
+ return mGlobal.injectInputEvent(event, mode);
}
/**
@@ -1149,20 +1109,12 @@
*/
@UnsupportedAppUsage
public void setPointerIconType(int iconId) {
- try {
- mIm.setPointerIconType(iconId);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ mGlobal.setPointerIconType(iconId);
}
/** @hide */
public void setCustomPointerIcon(PointerIcon icon) {
- try {
- mIm.setCustomPointerIcon(icon);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ mGlobal.setCustomPointerIcon(icon);
}
/**
@@ -1191,11 +1143,7 @@
* @hide
*/
public void requestPointerCapture(IBinder windowToken, boolean enable) {
- try {
- mIm.requestPointerCapture(windowToken, enable);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ mGlobal.requestPointerCapture(windowToken, enable);
}
/**
@@ -1204,11 +1152,7 @@
* @hide
*/
public InputMonitor monitorGestureInput(String name, int displayId) {
- try {
- return mIm.monitorGestureInput(new Binder(), name, displayId);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return mGlobal.monitorGestureInput(name, displayId);
}
/**
@@ -1313,12 +1257,9 @@
* @hide
*/
@TestApi
- public void addUniqueIdAssociation(@NonNull String inputPort, @NonNull String displayUniqueId) {
- try {
- mIm.addUniqueIdAssociation(inputPort, displayUniqueId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ public void addUniqueIdAssociation(@NonNull String inputPort,
+ @NonNull String displayUniqueId) {
+ mGlobal.addUniqueIdAssociation(inputPort, displayUniqueId);
}
/**
@@ -1331,11 +1272,7 @@
*/
@TestApi
public void removeUniqueIdAssociation(@NonNull String inputPort) {
- try {
- mIm.removeUniqueIdAssociation(inputPort);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ mGlobal.removeUniqueIdAssociation(inputPort);
}
/**
@@ -1361,11 +1298,7 @@
@RequiresPermission(Manifest.permission.BLUETOOTH)
@Nullable
public String getInputDeviceBluetoothAddress(int deviceId) {
- try {
- return mIm.getInputDeviceBluetoothAddress(deviceId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return mGlobal.getInputDeviceBluetoothAddress(deviceId);
}
/**
@@ -1423,11 +1356,7 @@
* @hide
*/
public void cancelCurrentTouch() {
- try {
- mIm.cancelCurrentTouch();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ mGlobal.cancelCurrentTouch();
}
/**
@@ -1451,11 +1380,7 @@
*/
@RequiresPermission(Manifest.permission.MONITOR_INPUT)
public void pilferPointers(IBinder inputChannelToken) {
- try {
- mIm.pilferPointers(inputChannelToken);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ mGlobal.pilferPointers(inputChannelToken);
}
/**
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 08d81bd..6e7e90e 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -30,19 +30,27 @@
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
import android.hardware.lights.LightsRequest;
+import android.os.Binder;
import android.os.CombinedVibration;
import android.os.Handler;
import android.os.IBinder;
import android.os.IVibratorStateListener;
+import android.os.InputEventInjectionSync;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.os.VibratorManager;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputMonitor;
+import android.view.PointerIcon;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.SomeArgs;
@@ -359,6 +367,42 @@
}
/**
+ * @see InputManager#isInputDeviceEnabled(int)
+ */
+ public boolean isInputDeviceEnabled(int id) {
+ try {
+ return mIm.isInputDeviceEnabled(id);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not check enabled status of input device with id = " + id);
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#enableInputDevice(int)
+ */
+ public void enableInputDevice(int id) {
+ try {
+ mIm.enableInputDevice(id);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not enable input device with id = " + id);
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#disableInputDevice(int)
+ */
+ public void disableInputDevice(int id) {
+ try {
+ mIm.disableInputDevice(id);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not disable input device with id = " + id);
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* @see InputManager#getInputDeviceByDescriptor
*/
InputDevice getInputDeviceByDescriptor(String descriptor) {
@@ -672,7 +716,7 @@
* @see InputManager#getInputDeviceBatteryState(int, boolean)
*/
@NonNull
- BatteryState getInputDeviceBatteryState(int deviceId, boolean hasBattery) {
+ public BatteryState getInputDeviceBatteryState(int deviceId, boolean hasBattery) {
if (!hasBattery) {
return new LocalBatteryState();
}
@@ -835,7 +879,7 @@
* @see InputManager#getInputDeviceSensorManager(int)
*/
@NonNull
- SensorManager getInputDeviceSensorManager(int deviceId) {
+ public SensorManager getInputDeviceSensorManager(int deviceId) {
if (mInputDeviceSensorManager == null) {
mInputDeviceSensorManager = new InputDeviceSensorManager(this);
}
@@ -980,6 +1024,21 @@
}
}
+ /**
+ * @see InputManager#getInputDeviceVibrator(int, int)
+ */
+ public Vibrator getInputDeviceVibrator(int deviceId, int vibratorId) {
+ return new InputDeviceVibrator(deviceId, vibratorId);
+ }
+
+ /**
+ * @see InputManager#getInputDeviceVibratorManager(int)
+ */
+ @NonNull
+ public VibratorManager getInputDeviceVibratorManager(int deviceId) {
+ return new InputDeviceVibratorManager(deviceId);
+ }
+
/*
* Get the list of device vibrators
* @return The list of vibrators IDs
@@ -1057,4 +1116,158 @@
throw ex.rethrowFromSystemServer();
}
}
+
+ /**
+ * @see InputManager#deviceHasKeys(int, int[])
+ */
+ public boolean[] deviceHasKeys(int id, int[] keyCodes) {
+ boolean[] ret = new boolean[keyCodes.length];
+ try {
+ mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ return ret;
+ }
+
+ /**
+ * @see InputManager#getKeyCodeforKeyLocation(int, int)
+ */
+ public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) {
+ try {
+ return mIm.getKeyCodeForKeyLocation(deviceId, locationKeyCode);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#injectInputEvent(InputEvent, int, int)
+ */
+
+ public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+ if (mode != InputEventInjectionSync.NONE
+ && mode != InputEventInjectionSync.WAIT_FOR_FINISHED
+ && mode != InputEventInjectionSync.WAIT_FOR_RESULT) {
+ throw new IllegalArgumentException("mode is invalid");
+ }
+
+ try {
+ return mIm.injectInputEventToTarget(event, mode, targetUid);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#injectInputEvent(InputEvent, int)
+ */
+ public boolean injectInputEvent(InputEvent event, int mode) {
+ return injectInputEvent(event, mode, Process.INVALID_UID);
+ }
+
+ /**
+ * @see InputManager#setPointerIconType(int)
+ */
+ public void setPointerIconType(int iconId) {
+ try {
+ mIm.setPointerIconType(iconId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#setCustomPointerIcon(PointerIcon)
+ */
+ public void setCustomPointerIcon(PointerIcon icon) {
+ try {
+ mIm.setCustomPointerIcon(icon);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#requestPointerCapture(IBinder, boolean)
+ */
+ void requestPointerCapture(IBinder windowToken, boolean enable) {
+ try {
+ mIm.requestPointerCapture(windowToken, enable);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see Inputmanager#monitorGestureInput(String, int)
+ */
+ InputMonitor monitorGestureInput(String name, int displayId) {
+ try {
+ return mIm.monitorGestureInput(new Binder(), name, displayId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#addUniqueIdAssociation(String, String)
+ */
+ void addUniqueIdAssociation(@NonNull String inputPort, @NonNull String displayUniqueId) {
+ try {
+ mIm.addUniqueIdAssociation(inputPort, displayUniqueId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#removeUniqueIdAssociation(String)
+ */
+ public void removeUniqueIdAssociation(@NonNull String inputPort) {
+ try {
+ mIm.removeUniqueIdAssociation(inputPort);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#getInputDeviceBluetoothAddress(int)
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @Nullable
+ public String getInputDeviceBluetoothAddress(int deviceId) {
+ try {
+ return mIm.getInputDeviceBluetoothAddress(deviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#cancelCurrentTouch()
+ */
+ void cancelCurrentTouch() {
+ try {
+ mIm.cancelCurrentTouch();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @see InputManager#pilferPointers(IBinder)
+ */
+ @RequiresPermission(Manifest.permission.MONITOR_INPUT)
+ void pilferPointers(IBinder inputChannelToken) {
+ try {
+ mIm.pilferPointers(inputChannelToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index b478a379..af09a06 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1295,19 +1295,31 @@
* value, such as 256MB or 32GB. This avoids showing weird values like
* "29.5GB" in UI.
*
+ * Some storage devices are still using GiB (powers of 1024) over
+ * GB (powers of 1000) measurements and this method takes it into account.
+ *
+ * Round ranges:
+ * ...
+ * [256 GiB + 1; 512 GiB] -> 512 GB
+ * [512 GiB + 1; 1 TiB] -> 1 TB
+ * [1 TiB + 1; 2 TiB] -> 2 TB
+ * etc
+ *
* @hide
*/
public static long roundStorageSize(long size) {
long val = 1;
- long pow = 1;
- while ((val * pow) < size) {
+ long kiloPow = 1;
+ long kibiPow = 1;
+ while ((val * kibiPow) < size) {
val <<= 1;
if (val > 512) {
val = 1;
- pow *= 1000;
+ kibiPow *= 1024;
+ kiloPow *= 1000;
}
}
- return val * pow;
+ return val * kiloPow;
}
private static long toBytes(long value, String unit) {
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index fcebb45..8e1d2d6 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -134,7 +134,7 @@
boolean isUserForeground(int userId);
boolean isUserVisible(int userId);
int[] getVisibleUsers();
- int getDisplayIdAssignedToUser();
+ int getMainDisplayIdAssignedToUser();
boolean isUserNameSet(int userId);
boolean hasRestrictedProfiles(int userId);
boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags);
diff --git a/core/java/android/os/PermissionEnforcer.java b/core/java/android/os/PermissionEnforcer.java
index 221e89a..310ceb3 100644
--- a/core/java/android/os/PermissionEnforcer.java
+++ b/core/java/android/os/PermissionEnforcer.java
@@ -18,9 +18,11 @@
import android.annotation.NonNull;
import android.annotation.SystemService;
+import android.app.AppOpsManager;
import android.content.AttributionSource;
import android.content.Context;
import android.content.PermissionChecker;
+import android.content.pm.PackageManager;
import android.permission.PermissionCheckerManager;
/**
@@ -40,6 +42,7 @@
public class PermissionEnforcer {
private final Context mContext;
+ private static final String ACCESS_DENIED = "Access denied, requires: ";
/** Protected constructor. Allows subclasses to instantiate an object
* without using a Context.
@@ -59,11 +62,42 @@
mContext, permission, PermissionChecker.PID_UNKNOWN, source, "" /* message */);
}
+ @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
+ @PermissionCheckerManager.PermissionResult
+ protected int checkPermission(@NonNull String permission, int pid, int uid) {
+ if (mContext.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
+ return PermissionCheckerManager.PERMISSION_GRANTED;
+ }
+ return PermissionCheckerManager.PERMISSION_HARD_DENIED;
+ }
+
+ private boolean anyAppOps(@NonNull String[] permissions) {
+ for (String permission : permissions) {
+ if (AppOpsManager.permissionToOpCode(permission) != AppOpsManager.OP_NONE) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public void enforcePermission(@NonNull String permission, @NonNull
AttributionSource source) throws SecurityException {
int result = checkPermission(permission, source);
if (result != PermissionCheckerManager.PERMISSION_GRANTED) {
- throw new SecurityException("Access denied, requires: " + permission);
+ throw new SecurityException(ACCESS_DENIED + permission);
+ }
+ }
+
+ public void enforcePermission(@NonNull String permission, int pid, int uid)
+ throws SecurityException {
+ if (AppOpsManager.permissionToOpCode(permission) != AppOpsManager.OP_NONE) {
+ AttributionSource source = new AttributionSource(uid, null, null);
+ enforcePermission(permission, source);
+ return;
+ }
+ int result = checkPermission(permission, pid, uid);
+ if (result != PermissionCheckerManager.PERMISSION_GRANTED) {
+ throw new SecurityException(ACCESS_DENIED + permission);
}
}
@@ -72,7 +106,23 @@
for (String permission : permissions) {
int result = checkPermission(permission, source);
if (result != PermissionCheckerManager.PERMISSION_GRANTED) {
- throw new SecurityException("Access denied, requires: allOf={"
+ throw new SecurityException(ACCESS_DENIED + "allOf={"
+ + String.join(", ", permissions) + "}");
+ }
+ }
+ }
+
+ public void enforcePermissionAllOf(@NonNull String[] permissions,
+ int pid, int uid) throws SecurityException {
+ if (anyAppOps(permissions)) {
+ AttributionSource source = new AttributionSource(uid, null, null);
+ enforcePermissionAllOf(permissions, source);
+ return;
+ }
+ for (String permission : permissions) {
+ int result = checkPermission(permission, pid, uid);
+ if (result != PermissionCheckerManager.PERMISSION_GRANTED) {
+ throw new SecurityException(ACCESS_DENIED + "allOf={"
+ String.join(", ", permissions) + "}");
}
}
@@ -86,7 +136,24 @@
return;
}
}
- throw new SecurityException("Access denied, requires: anyOf={"
+ throw new SecurityException(ACCESS_DENIED + "anyOf={"
+ + String.join(", ", permissions) + "}");
+ }
+
+ public void enforcePermissionAnyOf(@NonNull String[] permissions,
+ int pid, int uid) throws SecurityException {
+ if (anyAppOps(permissions)) {
+ AttributionSource source = new AttributionSource(uid, null, null);
+ enforcePermissionAnyOf(permissions, source);
+ return;
+ }
+ for (String permission : permissions) {
+ int result = checkPermission(permission, pid, uid);
+ if (result == PermissionCheckerManager.PERMISSION_GRANTED) {
+ return;
+ }
+ }
+ throw new SecurityException(ACCESS_DENIED + "anyOf={"
+ String.join(", ", permissions) + "}");
}
diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java
index 878e141..970f419 100644
--- a/core/java/android/os/RemoteException.java
+++ b/core/java/android/os/RemoteException.java
@@ -21,6 +21,12 @@
/**
* Parent exception for all Binder remote-invocation errors
+ *
+ * Note: not all exceptions from binder services will be subclasses of this.
+ * For instance, RuntimeException and several subclasses of it may be
+ * thrown as well as OutOfMemoryException.
+ *
+ * One common subclass is {@link DeadObjectException}.
*/
public class RemoteException extends AndroidException {
public RemoteException() {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 86e678d..b3604da 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3056,14 +3056,14 @@
}
/**
- * See {@link com.android.server.pm.UserManagerInternal#getDisplayAssignedToUser(int)}.
+ * See {@link com.android.server.pm.UserManagerInternal#getMainDisplayAssignedToUser(int)}.
*
* @hide
*/
@TestApi
- public int getDisplayIdAssignedToUser() {
+ public int getMainDisplayIdAssignedToUser() {
try {
- return mService.getDisplayIdAssignedToUser();
+ return mService.getMainDisplayIdAssignedToUser();
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index b117a9a..6f2a915 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -141,12 +141,15 @@
private int mRingerMode;
private int mZenMode;
private boolean mPlaySample;
+ private final boolean mDeviceHasProductStrategies;
private static final int MSG_SET_STREAM_VOLUME = 0;
private static final int MSG_START_SAMPLE = 1;
private static final int MSG_STOP_SAMPLE = 2;
private static final int MSG_INIT_SAMPLE = 3;
+ private static final int MSG_UPDATE_SLIDER_MAYBE_LATER = 4;
private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
+ private static final int CHECK_UPDATE_SLIDER_LATER_MS = 500;
private static final long SET_STREAM_VOLUME_DELAY_MS = TimeUnit.MILLISECONDS.toMillis(500);
private static final long START_SAMPLE_DELAY_MS = TimeUnit.MILLISECONDS.toMillis(500);
private static final long DURATION_TO_START_DELAYING = TimeUnit.MILLISECONDS.toMillis(2000);
@@ -170,6 +173,7 @@
boolean playSample) {
mContext = context;
mAudioManager = context.getSystemService(AudioManager.class);
+ mDeviceHasProductStrategies = hasAudioProductStrategies();
mNotificationManager = context.getSystemService(NotificationManager.class);
mNotificationPolicy = mNotificationManager.getConsolidatedNotificationPolicy();
mAllowAlarms = (mNotificationPolicy.priorityCategories & NotificationManager.Policy
@@ -186,7 +190,7 @@
}
mZenMode = mNotificationManager.getZenMode();
- if (hasAudioProductStrategies()) {
+ if (mDeviceHasProductStrategies) {
mVolumeGroupId = getVolumeGroupIdForLegacyStreamType(mStreamType);
mAttributes = getAudioAttributesForLegacyStreamType(
mStreamType);
@@ -213,6 +217,12 @@
mDefaultUri = defaultUri;
}
+ /**
+ * DO NOT CALL every time this is needed, use once in constructor,
+ * read mDeviceHasProductStrategies instead
+ * @return true if stream types are used for volume management, false if volume groups are
+ * used for volume management
+ */
private boolean hasAudioProductStrategies() {
return AudioManager.getAudioProductStrategies().size() > 0;
}
@@ -330,6 +340,9 @@
onInitSample();
}
break;
+ case MSG_UPDATE_SLIDER_MAYBE_LATER:
+ onUpdateSliderMaybeLater();
+ break;
default:
Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what);
}
@@ -353,6 +366,21 @@
: isDelay() ? START_SAMPLE_DELAY_MS : 0);
}
+ private void onUpdateSliderMaybeLater() {
+ if (isDelay()) {
+ postUpdateSliderMaybeLater();
+ return;
+ }
+ updateSlider();
+ }
+
+ private void postUpdateSliderMaybeLater() {
+ if (mHandler == null) return;
+ mHandler.removeMessages(MSG_UPDATE_SLIDER_MAYBE_LATER);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SLIDER_MAYBE_LATER),
+ CHECK_UPDATE_SLIDER_LATER_MS);
+ }
+
// After stop volume it needs to add a small delay when playing volume or set stream.
// It is because the call volume is from the earpiece and the alarm/ring/media
// is from the speaker. If play the alarm volume or set alarm stream right after stop
@@ -422,7 +450,7 @@
postStopSample();
mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
mReceiver.setListening(false);
- if (hasAudioProductStrategies()) {
+ if (mDeviceHasProductStrategies) {
unregisterVolumeGroupCb();
}
mSeekBar.setOnSeekBarChangeListener(null);
@@ -442,7 +470,7 @@
System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
false, mVolumeObserver);
mReceiver.setListening(true);
- if (hasAudioProductStrategies()) {
+ if (mDeviceHasProductStrategies) {
registerVolumeGroupCb();
}
}
@@ -466,6 +494,7 @@
mLastProgress = progress;
mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
mHandler.removeMessages(MSG_START_SAMPLE);
+ mHandler.removeMessages(MSG_UPDATE_SLIDER_MAYBE_LATER);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME),
isDelay() ? SET_STREAM_VOLUME_DELAY_MS : 0);
}
@@ -609,7 +638,7 @@
if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
- if (hasAudioProductStrategies() && !isDelay()) {
+ if (mDeviceHasProductStrategies && !isDelay()) {
updateVolumeSlider(streamType, streamValue);
}
} else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -621,9 +650,16 @@
}
} else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (hasAudioProductStrategies() && !isDelay()) {
- int streamVolume = mAudioManager.getStreamVolume(streamType);
- updateVolumeSlider(streamType, streamVolume);
+
+ if (mDeviceHasProductStrategies) {
+ if (isDelay()) {
+ // not the right time to update the sliders, try again later
+ postUpdateSliderMaybeLater();
+ } else {
+ int streamVolume = mAudioManager.getStreamVolume(streamType);
+ updateVolumeSlider(streamType, streamVolume);
+ }
+
} else {
int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType);
if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
diff --git a/core/java/android/service/credentials/Action.java b/core/java/android/service/credentials/Action.java
index 7487ac0..55133ae 100644
--- a/core/java/android/service/credentials/Action.java
+++ b/core/java/android/service/credentials/Action.java
@@ -17,7 +17,6 @@
package android.service.credentials;
import android.annotation.NonNull;
-import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.os.Parcel;
@@ -31,14 +30,8 @@
*
* <p>If user selects this action entry, the corresponding {@link PendingIntent} set on the
* {@code slice} as a {@link androidx.slice.core.SliceAction} will get invoked.
- *
- * <p>Any class that derives this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
*/
-@SuppressLint("ParcelNotFinal")
-public class Action implements Parcelable {
+public final class Action implements Parcelable {
/** Slice object containing display content to be displayed with this action on the UI. */
@NonNull
private final Slice mSlice;
diff --git a/core/java/android/service/credentials/BeginCreateCredentialRequest.java b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
index 1ca0049..89aaa5b 100644
--- a/core/java/android/service/credentials/BeginCreateCredentialRequest.java
+++ b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,14 +28,8 @@
* Request for beginning a create credential request.
*
* See {@link BeginCreateCredentialResponse} for the counterpart response
- *
- * <p>Any class that derives this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
*/
-@SuppressLint("ParcelNotFinal")
-public class BeginCreateCredentialRequest implements Parcelable {
+public final class BeginCreateCredentialRequest implements Parcelable {
private final @Nullable CallingAppInfo mCallingAppInfo;
private final @NonNull String mType;
private final @NonNull Bundle mData;
diff --git a/core/java/android/service/credentials/BeginGetCredentialOption.java b/core/java/android/service/credentials/BeginGetCredentialOption.java
index 1ad0424..b5f82d8 100644
--- a/core/java/android/service/credentials/BeginGetCredentialOption.java
+++ b/core/java/android/service/credentials/BeginGetCredentialOption.java
@@ -17,7 +17,6 @@
package android.service.credentials;
import android.annotation.NonNull;
-import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,14 +28,8 @@
* A specific type of credential request to be sent to the provider during the query phase of
* a get flow. This request contains limited parameters needed to populate a list of
* {@link CredentialEntry} on the {@link BeginGetCredentialResponse}.
- *
- * <p>Any class that derives this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
*/
-@SuppressLint("ParcelNotFinal")
-public class BeginGetCredentialOption implements Parcelable {
+public final class BeginGetCredentialOption implements Parcelable {
private static final String BUNDLE_ID_KEY =
"android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY";
/**
diff --git a/core/java/android/service/credentials/CreateEntry.java b/core/java/android/service/credentials/CreateEntry.java
index 106e65c..6a9f09f 100644
--- a/core/java/android/service/credentials/CreateEntry.java
+++ b/core/java/android/service/credentials/CreateEntry.java
@@ -17,7 +17,6 @@
package android.service.credentials;
import android.annotation.NonNull;
-import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.os.Parcel;
@@ -33,14 +32,8 @@
* the {@link android.app.Activity} result should be set to {@link android.app.Activity#RESULT_OK},
* and the {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESPONSE} must be set with a
* {@link android.credentials.CreateCredentialResponse} object.
- *
- * <p>Any class that derives this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
*/
-@SuppressLint("ParcelNotFinal")
-public class CreateEntry implements Parcelable {
+public final class CreateEntry implements Parcelable {
private final @NonNull Slice mSlice;
private CreateEntry(@NonNull Parcel in) {
diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java
index e9cebd2..512d833 100644
--- a/core/java/android/service/credentials/CredentialEntry.java
+++ b/core/java/android/service/credentials/CredentialEntry.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.credentials.GetCredentialResponse;
@@ -44,19 +43,8 @@
* result should be set to {@link android.app.Activity#RESULT_OK}, and the
* {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} must be set with a
* {@link GetCredentialResponse} object.
- *
- * <p>Any class that derives this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
- *
- * <p>While creating this entry, providers must set a {@code requestId} to be retrieved
- * from {@link BeginGetCredentialOption#getId()}, to determine for which request this entry is
- * being presented to the user. This will ensure that when user selects the entry, the correct
- * complete request is added to the {@link PendingIntent} mentioned above.
*/
-@SuppressLint("ParcelNotFinal")
-public class CredentialEntry implements Parcelable {
+public final class CredentialEntry implements Parcelable {
/** The request option that corresponds to this entry. **/
private final @Nullable String mBeginGetCredentialOptionId;
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index ea86fcc..47b75d1 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -163,28 +163,12 @@
private static boolean isSystemProviderWithValidPermission(
ServiceInfo serviceInfo, Context context) {
- requireNonNull(context, "context must not be null");
-
- final String permission = Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE;
- try {
- ApplicationInfo appInfo =
- context.getPackageManager()
- .getApplicationInfo(
- serviceInfo.packageName,
- PackageManager.ApplicationInfoFlags.of(
- PackageManager.MATCH_SYSTEM_ONLY));
- if (appInfo != null
- && context.checkPermission(permission, /* pid= */ -1, appInfo.uid)
- == PackageManager.PERMISSION_GRANTED) {
- Slog.i(TAG, "SYS permission granted for: " + serviceInfo.packageName);
- return true;
- } else {
- Slog.i(TAG, "SYS permission failed for: " + serviceInfo.packageName);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "Error getting info for " + serviceInfo + ": " + e);
+ if (context == null) {
+ Slog.w(TAG, "Context is null in isSystemProviderWithValidPermission");
+ return false;
}
- return false;
+ return PermissionUtils.hasPermission(context, serviceInfo.packageName,
+ Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE);
}
private static boolean isValidSystemProvider(
@@ -357,16 +341,6 @@
Log.e(TAG, "Failed to get capabilities: ", e);
}
- try {
- String[] discovered =
- metadata.getStringArray(CredentialProviderService.CAPABILITY_META_DATA_KEY);
- if (discovered != null) {
- capabilities.addAll(Arrays.asList(discovered));
- }
- } catch (Resources.NotFoundException | NullPointerException e) {
- Log.e(TAG, "Failed to get capabilities: ", e);
- }
-
if (capabilities.size() == 0) {
Log.e(TAG, "No capabilities found for provider:" + serviceInfo);
return output;
diff --git a/core/java/android/service/credentials/PermissionUtils.java b/core/java/android/service/credentials/PermissionUtils.java
new file mode 100644
index 0000000..c8bb202
--- /dev/null
+++ b/core/java/android/service/credentials/PermissionUtils.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.service.credentials;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+
+/**
+ * Utils for checking permissions, or any other permission related function
+ *
+ * @hide
+ */
+public class PermissionUtils {
+ //TODO(274838409): Move all CredentialManagerService permission checks here
+
+ /** Checks whether the given package name hold the given permission **/
+ public static boolean hasPermission(Context context, String packageName, String permission) {
+ try {
+ ApplicationInfo appInfo =
+ context.getPackageManager()
+ .getApplicationInfo(
+ packageName,
+ PackageManager.ApplicationInfoFlags.of(
+ PackageManager.MATCH_SYSTEM_ONLY));
+ if (appInfo != null
+ && context.checkPermission(permission, /* pid= */ -1, appInfo.uid)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ return false;
+ }
+}
+
diff --git a/core/java/android/service/credentials/RemoteEntry.java b/core/java/android/service/credentials/RemoteEntry.java
index 716c00d..5b3218a 100644
--- a/core/java/android/service/credentials/RemoteEntry.java
+++ b/core/java/android/service/credentials/RemoteEntry.java
@@ -17,7 +17,6 @@
package android.service.credentials;
import android.annotation.NonNull;
-import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.os.Parcel;
@@ -40,14 +39,8 @@
* For a creates flow, invoked through {@link CredentialProviderService#onBeginCreateCredential},
* providers must set a {@link android.credentials.CreateCredentialResponse} on the activity
* result against the ket {@link CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESPONSE}.
- *
- * <p>Any class that extends this class must only add extra field values to the {@code slice}
- * object passed into the constructor. Any other field will not be parceled through. If the
- * derived class has custom parceling implementation, this class will not be able to unpack
- * the parcel without having access to that implementation.
*/
-@SuppressLint("ParcelNotFinal")
-public class RemoteEntry implements Parcelable {
+public final class RemoteEntry implements Parcelable {
private final @NonNull Slice mSlice;
private RemoteEntry(@NonNull Parcel in) {
diff --git a/core/java/android/service/voice/HotwordDetectedResult.java b/core/java/android/service/voice/HotwordDetectedResult.java
index a1c5593..ff6dffd 100644
--- a/core/java/android/service/voice/HotwordDetectedResult.java
+++ b/core/java/android/service/voice/HotwordDetectedResult.java
@@ -293,6 +293,9 @@
*
* <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
* and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ *
+ * <p> This value is unitless. The relation between this value and the real audio signal
+ * power measured in decibels depends on the hotword detection service implementation.
*/
private final int mBackgroundAudioPower;
private static int defaultBackgroundAudioPower() {
@@ -749,6 +752,9 @@
*
* <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
* and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ *
+ * <p> This value is unitless. The relation between this value and the real audio signal
+ * power measured in decibels depends on the hotword detection service implementation.
*/
@DataClass.Generated.Member
public int getBackgroundAudioPower() {
@@ -1090,6 +1096,9 @@
*
* <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
* and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ *
+ * <p> This value is unitless. The relation between this value and the real audio signal
+ * power measured in decibels depends on the hotword detection service implementation.
*/
@DataClass.Generated.Member
public @NonNull Builder setBackgroundAudioPower(int value) {
@@ -1165,7 +1174,7 @@
}
@DataClass.Generated(
- time = 1679081102676L,
+ time = 1679517179528L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java",
inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\npublic static final int BACKGROUND_AUDIO_POWER_UNSET\nprivate static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE\nprivate static final java.lang.String EXTRA_PROXIMITY\npublic static final int PROXIMITY_UNKNOWN\npublic static final int PROXIMITY_NEAR\npublic static final int PROXIMITY_FAR\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final int mHotwordPhraseId\nprivate final @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> mAudioStreams\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int sMaxBundleSize\nprivate final int mBackgroundAudioPower\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\nprivate static int defaultHotwordPhraseId()\npublic static int getMaxHotwordPhraseId()\nprivate static java.util.List<android.service.voice.HotwordAudioStream> defaultAudioStreams()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\nprivate static int defaultBackgroundAudioPower()\npublic static int getMaxBackgroundAudioPower()\npublic static int getParcelableSize(android.os.Parcelable)\npublic static int getUsageSize(android.service.voice.HotwordDetectedResult)\nprivate static int bitCount(long)\nprivate void onConstructed()\npublic @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> getAudioStreams()\npublic void setProximity(double)\npublic @android.service.voice.HotwordDetectedResult.ProximityValue int getProximity()\nprivate @android.service.voice.HotwordDetectedResult.ProximityValue int convertToProximityLevel(double)\npublic android.service.voice.HotwordDetectedResult.Builder buildUpon()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/java/android/util/DataUnit.java b/core/java/android/util/DataUnit.java
index cf045b8..cc33af3 100644
--- a/core/java/android/util/DataUnit.java
+++ b/core/java/android/util/DataUnit.java
@@ -36,9 +36,11 @@
KILOBYTES { @Override public long toBytes(long v) { return v * 1_000; } },
MEGABYTES { @Override public long toBytes(long v) { return v * 1_000_000; } },
GIGABYTES { @Override public long toBytes(long v) { return v * 1_000_000_000; } },
+ TERABYTES { @Override public long toBytes(long v) { return v * 1_000_000_000_000L; } },
KIBIBYTES { @Override public long toBytes(long v) { return v * 1_024; } },
MEBIBYTES { @Override public long toBytes(long v) { return v * 1_048_576; } },
- GIBIBYTES { @Override public long toBytes(long v) { return v * 1_073_741_824; } };
+ GIBIBYTES { @Override public long toBytes(long v) { return v * 1_073_741_824; } },
+ TEBIBYTES { @Override public long toBytes(long v) { return v * 1_099_511_627_776L; } };
public long toBytes(long v) {
throw new AbstractMethodError();
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 6201b3a..bc514b0 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -229,9 +229,9 @@
DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false");
DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "true");
DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_ENROLLMENT, "false");
- DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, "false");
+ DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, "true");
DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false");
- DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
+ DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "true");
DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true");
DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "false");
diff --git a/core/java/android/util/SafetyProtectionUtils.java b/core/java/android/util/SafetyProtectionUtils.java
index af985c5..75eaa9e 100644
--- a/core/java/android/util/SafetyProtectionUtils.java
+++ b/core/java/android/util/SafetyProtectionUtils.java
@@ -40,14 +40,20 @@
* @hide
*/
public static boolean shouldShowSafetyProtectionResources(Context context) {
- return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- SAFETY_PROTECTION_RESOURCES_ENABLED, false)
- && context.getResources().getBoolean(
- Resources.getSystem()
- .getIdentifier("config_safetyProtectionEnabled",
- "bool", "android"))
- && context.getDrawable(android.R.drawable.ic_safety_protection) != null
- && context.getString(android.R.string.safety_protection_display_text) != null
- && !context.getString(android.R.string.safety_protection_display_text).isEmpty();
+ try {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+ SAFETY_PROTECTION_RESOURCES_ENABLED, false)
+ && context.getResources().getBoolean(
+ Resources.getSystem()
+ .getIdentifier("config_safetyProtectionEnabled",
+ "bool", "android"))
+ && context.getDrawable(android.R.drawable.ic_safety_protection) != null
+ && !context.getString(
+ android.R.string.safety_protection_display_text).isEmpty();
+ } catch (Resources.NotFoundException e) {
+ // We should expect the resources to not exist for non-pixel devices
+ // (except for the OEMs that opt-in)
+ return false;
+ }
}
}
diff --git a/core/java/android/view/ContentRecordingSession.java b/core/java/android/view/ContentRecordingSession.java
index c66c70af..c1c1317 100644
--- a/core/java/android/view/ContentRecordingSession.java
+++ b/core/java/android/view/ContentRecordingSession.java
@@ -25,7 +25,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DataClass;
import java.lang.annotation.Retention;
@@ -72,11 +71,18 @@
* If {@link #getContentToRecord()} is {@link RecordContent#RECORD_CONTENT_TASK}, then
* represents the {@link android.window.WindowContainerToken} of the Task to record.
*/
- @VisibleForTesting
@Nullable
private IBinder mTokenToRecord = null;
/**
+ * When {@code true}, no mirroring should take place until the user has re-granted access to
+ * the consent token. When {@code false}, recording can begin immediately.
+ *
+ * <p>Only set on the server side to sanitize any input from the client process.
+ */
+ private boolean mWaitingToRecord = false;
+
+ /**
* Default instance, with recording the display.
*/
private ContentRecordingSession() {
@@ -109,9 +115,10 @@
}
/**
- * Returns {@code true} when both sessions are for the same display.
+ * Returns {@code true} when both sessions are on the same
+ * {@link android.hardware.display.VirtualDisplay}.
*/
- public static boolean isSameDisplay(ContentRecordingSession session,
+ public static boolean isProjectionOnSameDisplay(ContentRecordingSession session,
ContentRecordingSession incomingSession) {
return session != null && incomingSession != null
&& session.getDisplayId() == incomingSession.getDisplayId();
@@ -156,7 +163,8 @@
/* package-private */ ContentRecordingSession(
int displayId,
@RecordContent int contentToRecord,
- @VisibleForTesting @Nullable IBinder tokenToRecord) {
+ @Nullable IBinder tokenToRecord,
+ boolean waitingToRecord) {
this.mDisplayId = displayId;
this.mContentToRecord = contentToRecord;
@@ -169,8 +177,7 @@
}
this.mTokenToRecord = tokenToRecord;
- com.android.internal.util.AnnotationValidations.validate(
- VisibleForTesting.class, null, mTokenToRecord);
+ this.mWaitingToRecord = waitingToRecord;
// onConstructed(); // You can define this method to get a callback
}
@@ -200,11 +207,22 @@
* represents the {@link android.window.WindowContainerToken} of the Task to record.
*/
@DataClass.Generated.Member
- public @VisibleForTesting @Nullable IBinder getTokenToRecord() {
+ public @Nullable IBinder getTokenToRecord() {
return mTokenToRecord;
}
/**
+ * When {@code true}, no mirroring should take place until the user has re-granted access to
+ * the consent token. When {@code false}, recording can begin immediately.
+ *
+ * <p>Only set on the server side to sanitize any input from the client process.
+ */
+ @DataClass.Generated.Member
+ public boolean isWaitingToRecord() {
+ return mWaitingToRecord;
+ }
+
+ /**
* Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
* recorded content rendered to its surface.
*/
@@ -240,10 +258,20 @@
* represents the {@link android.window.WindowContainerToken} of the Task to record.
*/
@DataClass.Generated.Member
- public @NonNull ContentRecordingSession setTokenToRecord(@VisibleForTesting @NonNull IBinder value) {
+ public @NonNull ContentRecordingSession setTokenToRecord(@NonNull IBinder value) {
mTokenToRecord = value;
- com.android.internal.util.AnnotationValidations.validate(
- VisibleForTesting.class, null, mTokenToRecord);
+ return this;
+ }
+
+ /**
+ * When {@code true}, no mirroring should take place until the user has re-granted access to
+ * the consent token. When {@code false}, recording can begin immediately.
+ *
+ * <p>Only set on the server side to sanitize any input from the client process.
+ */
+ @DataClass.Generated.Member
+ public @NonNull ContentRecordingSession setWaitingToRecord( boolean value) {
+ mWaitingToRecord = value;
return this;
}
@@ -256,7 +284,8 @@
return "ContentRecordingSession { " +
"displayId = " + mDisplayId + ", " +
"contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
- "tokenToRecord = " + mTokenToRecord +
+ "tokenToRecord = " + mTokenToRecord + ", " +
+ "waitingToRecord = " + mWaitingToRecord +
" }";
}
@@ -275,7 +304,8 @@
return true
&& mDisplayId == that.mDisplayId
&& mContentToRecord == that.mContentToRecord
- && java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord);
+ && java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord)
+ && mWaitingToRecord == that.mWaitingToRecord;
}
@Override
@@ -288,6 +318,7 @@
_hash = 31 * _hash + mDisplayId;
_hash = 31 * _hash + mContentToRecord;
_hash = 31 * _hash + java.util.Objects.hashCode(mTokenToRecord);
+ _hash = 31 * _hash + Boolean.hashCode(mWaitingToRecord);
return _hash;
}
@@ -298,6 +329,7 @@
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
+ if (mWaitingToRecord) flg |= 0x8;
if (mTokenToRecord != null) flg |= 0x4;
dest.writeByte(flg);
dest.writeInt(mDisplayId);
@@ -317,6 +349,7 @@
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
+ boolean waitingToRecord = (flg & 0x8) != 0;
int displayId = in.readInt();
int contentToRecord = in.readInt();
IBinder tokenToRecord = (flg & 0x4) == 0 ? null : (IBinder) in.readStrongBinder();
@@ -333,8 +366,7 @@
}
this.mTokenToRecord = tokenToRecord;
- com.android.internal.util.AnnotationValidations.validate(
- VisibleForTesting.class, null, mTokenToRecord);
+ this.mWaitingToRecord = waitingToRecord;
// onConstructed(); // You can define this method to get a callback
}
@@ -362,7 +394,8 @@
private int mDisplayId;
private @RecordContent int mContentToRecord;
- private @VisibleForTesting @Nullable IBinder mTokenToRecord;
+ private @Nullable IBinder mTokenToRecord;
+ private boolean mWaitingToRecord;
private long mBuilderFieldsSet = 0L;
@@ -400,17 +433,31 @@
* represents the {@link android.window.WindowContainerToken} of the Task to record.
*/
@DataClass.Generated.Member
- public @NonNull Builder setTokenToRecord(@VisibleForTesting @NonNull IBinder value) {
+ public @NonNull Builder setTokenToRecord(@NonNull IBinder value) {
checkNotUsed();
mBuilderFieldsSet |= 0x4;
mTokenToRecord = value;
return this;
}
+ /**
+ * When {@code true}, no mirroring should take place until the user has re-granted access to
+ * the consent token. When {@code false}, recording can begin immediately.
+ *
+ * <p>Only set on the server side to sanitize any input from the client process.
+ */
+ @DataClass.Generated.Member
+ public @NonNull Builder setWaitingToRecord(boolean value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x8;
+ mWaitingToRecord = value;
+ return this;
+ }
+
/** Builds the instance. This builder should not be touched after calling this! */
public @NonNull ContentRecordingSession build() {
checkNotUsed();
- mBuilderFieldsSet |= 0x8; // Mark builder used
+ mBuilderFieldsSet |= 0x10; // Mark builder used
if ((mBuilderFieldsSet & 0x1) == 0) {
mDisplayId = INVALID_DISPLAY;
@@ -421,15 +468,19 @@
if ((mBuilderFieldsSet & 0x4) == 0) {
mTokenToRecord = null;
}
+ if ((mBuilderFieldsSet & 0x8) == 0) {
+ mWaitingToRecord = false;
+ }
ContentRecordingSession o = new ContentRecordingSession(
mDisplayId,
mContentToRecord,
- mTokenToRecord);
+ mTokenToRecord,
+ mWaitingToRecord);
return o;
}
private void checkNotUsed() {
- if ((mBuilderFieldsSet & 0x8) != 0) {
+ if ((mBuilderFieldsSet & 0x10) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}
@@ -437,10 +488,10 @@
}
@DataClass.Generated(
- time = 1645803878639L,
+ time = 1678817765846L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
- inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\nprivate int mDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate @com.android.internal.annotations.VisibleForTesting @android.annotation.Nullable android.os.IBinder mTokenToRecord\npublic static android.view.ContentRecordingSession createDisplaySession(android.os.IBinder)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
+ inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\nprivate int mDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate boolean mWaitingToRecord\npublic static android.view.ContentRecordingSession createDisplaySession(android.os.IBinder)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 6b60442..77f3b1d 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -151,14 +151,16 @@
// Either we've already tried to initiate handwriting, or the ongoing MotionEvent
// sequence is considered to be tap, long-click or other gestures.
if (!mState.mShouldInitHandwriting || mState.mExceedHandwritingSlop) {
- return mState.mHasInitiatedHandwriting;
+ return mState.mHasInitiatedHandwriting
+ || mState.mHasPreparedHandwritingDelegation;
}
final long timeElapsed =
motionEvent.getEventTime() - mState.mStylusDownTimeInMillis;
if (timeElapsed > mHandwritingTimeoutInMillis) {
mState.mShouldInitHandwriting = false;
- return mState.mHasInitiatedHandwriting;
+ return mState.mHasInitiatedHandwriting
+ || mState.mHasPreparedHandwritingDelegation;
}
final int pointerIndex = motionEvent.findPointerIndex(mState.mStylusPointerId);
@@ -183,12 +185,13 @@
mImm.prepareStylusHandwritingDelegation(
candidateView, delegatePackageName);
candidateView.getHandwritingDelegatorCallback().run();
+ mState.mHasPreparedHandwritingDelegation = true;
} else {
requestFocusWithoutReveal(candidateView);
}
}
}
- return mState.mHasInitiatedHandwriting;
+ return mState.mHasInitiatedHandwriting || mState.mHasPreparedHandwritingDelegation;
}
return false;
}
@@ -568,6 +571,8 @@
* Whether handwriting mode has already been initiated for the current MotionEvent sequence.
*/
private boolean mHasInitiatedHandwriting;
+
+ private boolean mHasPreparedHandwritingDelegation;
/**
* Whether the current ongoing stylus MotionEvent sequence already exceeds the
* handwriting slop.
@@ -593,6 +598,7 @@
mShouldInitHandwriting = true;
mHasInitiatedHandwriting = false;
+ mHasPreparedHandwritingDelegation = false;
mExceedHandwritingSlop = false;
}
}
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 61864d7..e81aecb 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -776,7 +776,7 @@
* Each gamepad or joystick is given a unique, positive controller number when initially
* configured by the system. This number may change due to events such as device disconnects /
* reconnects or user initiated reassignment. Any change in number will trigger an event that
- * can be observed by registering an {@link InputManager.InputDeviceListener}.
+ * can be observed by registering an {@link InputManagerGlobal.InputDeviceListener}.
* </p>
* <p>
* All input devices which are not gamepads or joysticks will be assigned a controller number
@@ -981,7 +981,7 @@
* generating the keycode given by the corresponding value at the same index in the keys array.
*/
public boolean[] hasKeys(int... keys) {
- return InputManager.getInstance().deviceHasKeys(mId, keys);
+ return InputManagerGlobal.getInstance().deviceHasKeys(mId, keys);
}
/**
@@ -1028,7 +1028,8 @@
* {@link InputDevice#SOURCE_KEYBOARD} or the requested mapping cannot be determined.
*/
public int getKeyCodeForKeyLocation(int locationKeyCode) {
- return InputManager.getInstance().getKeyCodeForKeyLocation(mId, locationKeyCode);
+ return InputManagerGlobal.getInstance()
+ .getKeyCodeForKeyLocation(mId, locationKeyCode);
}
/**
@@ -1109,9 +1110,11 @@
@RequiresPermission(Manifest.permission.BLUETOOTH)
@Nullable
public String getBluetoothAddress() {
- // We query the address via a separate InputManager API instead of pre-populating it in
- // this class to avoid leaking it to apps that do not have sufficient permissions.
- return InputManager.getInstance().getInputDeviceBluetoothAddress(mId);
+ // We query the address via a separate InputManagerGlobal API
+ // instead of pre-populating it in this class to avoid
+ // leaking it to apps that do not have sufficient permissions.
+ return InputManagerGlobal.getInstance()
+ .getInputDeviceBluetoothAddress(mId);
}
/**
@@ -1132,7 +1135,8 @@
synchronized (mMotionRanges) {
if (mVibrator == null) {
if (mHasVibrator) {
- mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId,
+ mVibrator = InputManagerGlobal.getInstance()
+ .getInputDeviceVibrator(mId,
VIBRATOR_ID_ALL);
} else {
mVibrator = NullVibrator.getInstance();
@@ -1154,7 +1158,8 @@
public VibratorManager getVibratorManager() {
synchronized (mMotionRanges) {
if (mVibratorManager == null) {
- mVibratorManager = InputManager.getInstance().getInputDeviceVibratorManager(mId);
+ mVibratorManager = InputManagerGlobal.getInstance()
+ .getInputDeviceVibratorManager(mId);
}
}
return mVibratorManager;
@@ -1170,7 +1175,8 @@
*/
@NonNull
public BatteryState getBatteryState() {
- return InputManager.getInstance().getInputDeviceBatteryState(mId, mHasBattery);
+ return InputManagerGlobal.getInstance()
+ .getInputDeviceBatteryState(mId, mHasBattery);
}
/**
@@ -1206,7 +1212,8 @@
public SensorManager getSensorManager() {
synchronized (mMotionRanges) {
if (mSensorManager == null) {
- mSensorManager = InputManager.getInstance().getInputDeviceSensorManager(mId);
+ mSensorManager = InputManagerGlobal.getInstance()
+ .getInputDeviceSensorManager(mId);
}
}
return mSensorManager;
@@ -1217,7 +1224,7 @@
* @return Whether the input device is enabled.
*/
public boolean isEnabled() {
- return InputManager.getInstance().isInputDeviceEnabled(mId);
+ return InputManagerGlobal.getInstance().isInputDeviceEnabled(mId);
}
/**
@@ -1228,7 +1235,7 @@
@RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
@TestApi
public void enable() {
- InputManager.getInstance().enableInputDevice(mId);
+ InputManagerGlobal.getInstance().enableInputDevice(mId);
}
/**
@@ -1239,7 +1246,7 @@
@RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
@TestApi
public void disable() {
- InputManager.getInstance().disableInputDevice(mId);
+ InputManagerGlobal.getInstance().disableInputDevice(mId);
}
/**
@@ -1274,7 +1281,7 @@
* @hide
*/
public void setPointerType(int pointerType) {
- InputManager.getInstance().setPointerIconType(pointerType);
+ InputManagerGlobal.getInstance().setPointerIconType(pointerType);
}
/**
@@ -1283,7 +1290,7 @@
* @hide
*/
public void setCustomPointerIcon(PointerIcon icon) {
- InputManager.getInstance().setCustomPointerIcon(icon);
+ InputManagerGlobal.getInstance().setCustomPointerIcon(icon);
}
/**
@@ -1301,7 +1308,7 @@
*
* @return the supported USI version, or null if the device does not support USI
* @see <a href="https://universalstylus.org">Universal Stylus Initiative</a>
- * @see InputManager#getHostUsiVersion(int)
+ * @see InputManagerGlobal#getHostUsiVersion(int)
* @hide
*/
@Nullable
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
index 867d2b4..a2e0326c 100644
--- a/core/java/android/view/InsetsFrameProvider.java
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -293,7 +293,7 @@
public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds,
Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize,
@WindowManager.LayoutParams.PrivateFlags int privateFlags,
- Insets displayCutoutSafeInsetsSize) {
+ Insets displayCutoutSafeInsetsSize, Rect givenContentInsets) {
boolean extendByCutout = false;
if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
inOutFrame.set(displayFrame);
@@ -301,16 +301,20 @@
inOutFrame.set(containerBounds);
} else {
extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0;
- }
- if (insetsSize == null) {
- return;
+ if (givenContentInsets != null) {
+ inOutFrame.inset(givenContentInsets);
+ }
}
if (displayCutoutSafeInsetsSize != null) {
sTmpRect2.set(inOutFrame);
}
- calculateInsetsFrame(inOutFrame, insetsSize);
+ if (insetsSize != null) {
+ calculateInsetsFrame(inOutFrame, insetsSize);
+ }
- if (extendByCutout) {
+ if (extendByCutout && insetsSize != null) {
+ // Only extend if the insets size is not null. Otherwise, the frame has already been
+ // extended by the display cutout during layout process.
WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect);
}
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index b574ecf..42ac74c 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -15,6 +15,10 @@
# Autofill
per-file ViewStructure.java = file:/core/java/android/service/autofill/OWNERS
+# Choreographer
+per-file Choreographer.java = file:platform/frameworks/native:/services/surfaceflinger/OWNERS
+per-file DisplayEventReceiver.java = file:platform/frameworks/native:/services/surfaceflinger/OWNERS
+
# Display
per-file Display*.java = file:/services/core/java/com/android/server/display/OWNERS
per-file Display*.aidl = file:/services/core/java/com/android/server/display/OWNERS
@@ -60,6 +64,9 @@
per-file SurfaceHolder.java = file:/graphics/java/android/graphics/OWNERS
per-file SurfaceHolder.java = file:/services/core/java/com/android/server/wm/OWNERS
+# Text
+per-file HandwritingInitiator.java = file:/core/java/android/text/OWNERS
+
# View
per-file View.java = file:/services/accessibility/OWNERS
per-file View.java = file:/core/java/android/service/autofill/OWNERS
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 4895aed..0db52aa 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -3896,10 +3896,12 @@
float currentBufferRatio, float desiredRatio) {
checkPreconditions(sc);
if (!Float.isFinite(currentBufferRatio) || currentBufferRatio < 1.0f) {
- throw new IllegalArgumentException("currentBufferRatio must be finite && >= 1.0f");
+ throw new IllegalArgumentException(
+ "currentBufferRatio must be finite && >= 1.0f; got " + currentBufferRatio);
}
if (!Float.isFinite(desiredRatio) || desiredRatio < 1.0f) {
- throw new IllegalArgumentException("desiredRatio must be finite && >= 1.0f");
+ throw new IllegalArgumentException(
+ "desiredRatio must be finite && >= 1.0f; got " + desiredRatio);
}
nativeSetExtendedRangeBrightness(mNativeObject, sc.mNativeObject, currentBufferRatio,
desiredRatio);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index d8b6b7b..b46a68c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -851,14 +851,10 @@
}
mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
- // Only control visibility if we're not hardware-accelerated. Otherwise we'll
- // let renderthread drive since offscreen SurfaceControls should not be visible.
- if (!isHardwareAccelerated()) {
- if (mViewVisibility) {
- surfaceUpdateTransaction.show(mSurfaceControl);
- } else {
- surfaceUpdateTransaction.hide(mSurfaceControl);
- }
+ if (mViewVisibility) {
+ surfaceUpdateTransaction.show(mSurfaceControl);
+ } else {
+ surfaceUpdateTransaction.hide(mSurfaceControl);
}
updateBackgroundVisibility(surfaceUpdateTransaction);
@@ -1421,10 +1417,12 @@
}
private final Rect mRTLastReportedPosition = new Rect();
+ private final Point mRTLastReportedSurfaceSize = new Point();
private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
private final int mRtSurfaceWidth;
private final int mRtSurfaceHeight;
+ private boolean mRtFirst = true;
private final SurfaceControl.Transaction mPositionChangedTransaction =
new SurfaceControl.Transaction();
@@ -1435,6 +1433,15 @@
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
+ if (!mRtFirst && (mRTLastReportedPosition.left == left
+ && mRTLastReportedPosition.top == top
+ && mRTLastReportedPosition.right == right
+ && mRTLastReportedPosition.bottom == bottom
+ && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
+ && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight)) {
+ return;
+ }
+ mRtFirst = false;
try {
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
@@ -1445,8 +1452,8 @@
}
synchronized (mSurfaceControlLock) {
if (mSurfaceControl == null) return;
-
mRTLastReportedPosition.set(left, top, right, bottom);
+ mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight);
onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl,
mRTLastReportedPosition.left /*positionLeft*/,
mRTLastReportedPosition.top /*positionTop*/,
@@ -1454,8 +1461,10 @@
/ (float) mRtSurfaceWidth /*postScaleX*/,
mRTLastReportedPosition.height()
/ (float) mRtSurfaceHeight /*postScaleY*/);
-
- mPositionChangedTransaction.show(mSurfaceControl);
+ if (mViewVisibility) {
+ // b/131239825
+ mPositionChangedTransaction.show(mSurfaceControl);
+ }
}
applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
} catch (Exception ex) {
@@ -1481,6 +1490,7 @@
System.identityHashCode(this), frameNumber));
}
mRTLastReportedPosition.setEmpty();
+ mRTLastReportedSurfaceSize.set(-1, -1);
// positionLost can be called while UI thread is un-paused.
synchronized (mSurfaceControlLock) {
diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING
index ecb98f9..1e39716 100644
--- a/core/java/android/view/TEST_MAPPING
+++ b/core/java/android/view/TEST_MAPPING
@@ -42,6 +42,9 @@
],
"imports": [
{
+ "path": "cts/tests/surfacecontrol"
+ },
+ {
"path": "cts/tests/tests/uirendering"
}
]
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index aec3487..6cd8941 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -163,7 +163,6 @@
import android.view.translation.ViewTranslationRequest;
import android.view.translation.ViewTranslationResponse;
import android.widget.Checkable;
-import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ScrollBarDrawable;
import android.window.OnBackInvokedDispatcher;
@@ -10347,24 +10346,29 @@
}
/**
- * Check whether current activity / package is in denylist.If it's in the denylist,
- * then the views marked as not important for autofill are not eligible for autofill.
+ * Check whether current activity / package is in autofill denylist.
+ *
+ * Called by viewGroup#populateChildrenForAutofill() to determine whether to include view in
+ * assist structure
*/
final boolean isActivityDeniedForAutofillForUnimportantView() {
final AutofillManager afm = getAutofillManager();
- // keep behavior same with denylist feature not enabled
- if (afm == null) return true;
- return afm.isActivityDeniedForAutofillForUnimportantView();
+ if (afm == null) return false;
+ return afm.isActivityDeniedForAutofill();
}
/**
* Check whether current view matches autofillable heuristics
+ *
+ * Called by viewGroup#populateChildrenForAutofill() to determine whether to include view in
+ * assist structure
*/
final boolean isMatchingAutofillableHeuristics() {
final AutofillManager afm = getAutofillManager();
- // keep default behavior
if (afm == null) return false;
- return afm.isMatchingAutofillableHeuristicsForNotImportantViews(this);
+ // check the flag to see if trigger fill request on not important views is enabled
+ return afm.isTriggerFillRequestOnUnimportantViewEnabled()
+ ? afm.isAutofillable(this) : false;
}
private boolean isAutofillable() {
@@ -10380,39 +10384,26 @@
return false;
}
- // Experiment imeAction heuristic on important views. If the important view doesn't pass
- // heuristic check, also check augmented autofill in case augmented autofill is enabled
- // for the activity
- // TODO: refactor to have both important views and not important views use the same
- // heuristic check
- if (isImportantForAutofill()
- && afm.isTriggerFillRequestOnFilteredImportantViewsEnabled()
- && this instanceof EditText
- && !afm.isPassingImeActionCheck((EditText) this)
- && !notifyAugmentedAutofillIfNeeded(afm)) {
- // TODO: add a log to indicate what has filtered out the view
+ // Check whether view is not part of an activity. If it's not, return false.
+ if (getAutofillViewId() <= LAST_APP_AUTOFILL_ID) {
return false;
}
- if (!isImportantForAutofill()) {
- // If view matches heuristics and is not denied, it will be treated same as view that's
- // important for autofill
- if (afm.isMatchingAutofillableHeuristicsForNotImportantViews(this)
- && !afm.isActivityDeniedForAutofillForUnimportantView()) {
- return getAutofillViewId() > LAST_APP_AUTOFILL_ID;
- }
- // View is not important for "regular" autofill, so we must check if Augmented Autofill
- // is enabled for the activity
- if (!notifyAugmentedAutofillIfNeeded(afm)){
- return false;
- }
+ // If view is important and filter important view flag is turned on, or view is not
+ // important and trigger fill request on not important view flag is turned on, then use
+ // AutofillManager.isAutofillable() to decide whether view is autofillable instead.
+ if ((isImportantForAutofill() && afm.isTriggerFillRequestOnFilteredImportantViewsEnabled())
+ || (!isImportantForAutofill()
+ && afm.isTriggerFillRequestOnUnimportantViewEnabled())) {
+ return afm.isAutofillable(this) ? true : notifyAugmentedAutofillIfNeeded(afm);
}
- return getAutofillViewId() > LAST_APP_AUTOFILL_ID;
+ // If the previous condition is not met, fall back to the previous way to trigger fill
+ // request based on autofill importance instead.
+ return isImportantForAutofill() ? true : notifyAugmentedAutofillIfNeeded(afm);
}
- /** @hide **/
- public boolean notifyAugmentedAutofillIfNeeded(AutofillManager afm) {
+ private boolean notifyAugmentedAutofillIfNeeded(AutofillManager afm) {
final AutofillOptions options = mContext.getAutofillOptions();
if (options == null || !options.isAugmentedAutofillEnabled(mContext)) {
return false;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d1f9fbd..152fa08 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -11365,9 +11365,13 @@
if (mRemoved || !isHardwareEnabled()) {
t.apply();
} else {
+ // Copy and clear the passed in transaction for thread safety. The new transaction is
+ // accessed on the render thread.
+ var localTransaction = new Transaction();
+ localTransaction.merge(t);
mHasPendingTransactions = true;
registerRtFrameCallback(frame -> {
- mergeWithNextTransaction(t, frame);
+ mergeWithNextTransaction(localTransaction, frame);
});
}
return true;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 9d82b79..ddd7734 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -832,9 +832,7 @@
private static final int BOOLEAN_PROPERTY_REQUEST_INITIAL_ACCESSIBILITY_FOCUS = 1 << 24;
- private static final int BOOLEAN_PROPERTY_REQUEST_TOUCH_PASSTHROUGH = 1 << 25;
-
- private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE = 1 << 26;
+ private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE = 1 << 25;
/**
* Bits that provide the id of a virtual descendant of a view.
@@ -2599,56 +2597,9 @@
}
/**
- * Gets whether this node is one of the candidates that wants touch interaction within its
- * screen bounds to bypass the touch exploration and go straight to the underlying view
- * hierarchy.
- *
- * <p>
- * {@link android.accessibilityservice.AccessibilityService} could aggregate the {@link
- * #getBoundsInScreen()} that has request touch passthrough, and/or doing complex calculation
- * with other views that doesn't request touch passthrough, and call {@link
- * AccessibilityService#setTouchExplorationPassthroughRegion(int, Region)} to bypass the touch
- * interactions to the underlying views within the region.
- * </p>
- *
- * @return True if the node wants touch interaction within its screen bounds to bypass touch
- * exploration and go straight to the underlying view hierarchy; false otherwise.
- */
- public boolean hasRequestTouchPassthrough() {
- return getBooleanProperty(BOOLEAN_PROPERTY_REQUEST_TOUCH_PASSTHROUGH);
- }
-
- /**
- * Sets whether this node wants touch interaction within its screen bounds to bypass touch
- * exploration and go straight to the underlying view hierarchy.
- * <p>
- * <strong>Note:</strong> This property allows the
- * {@link android.accessibilityservice.AccessibilityService} to calculate the
- * aggregated touch passthrough region. App developers need to ensure that the
- * {@link #getBoundsInScreen()} of
- * the node align with the region they want touchable, and that child nodes overlapping these
- * bounds may cause that region to be reduced.
- * </p>
- *
- * <p>
- * <strong>Note:</strong> Cannot be called from an
- * {@link android.accessibilityservice.AccessibilityService}.
- * This class is made immutable before being delivered to an AccessibilityService.
- * </p>
- *
- * @param touchPassthrough True if the node wants touch interaction within its screen bounds
- * to bypass touch exploration and go straight to the underlying view
- * hierarchy.
- * @throws IllegalStateException If called from an AccessibilityService.
- */
- public void setRequestTouchPassthrough(boolean touchPassthrough) {
- setBooleanProperty(BOOLEAN_PROPERTY_REQUEST_TOUCH_PASSTHROUGH, touchPassthrough);
- }
-
- /**
* Gets if the node's accessibility data is considered sensitive.
*
- * @return True if the node is editable, false otherwise.
+ * @return True if the node's data is considered sensitive, false otherwise.
* @see View#isAccessibilityDataSensitive()
*/
public boolean isAccessibilityDataSensitive() {
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index 7da69e7..e267a7f 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -365,7 +365,10 @@
}
/**
- * Get denylist string from flag
+ * Get denylist string from flag.
+ *
+ * Note: This denylist works both on important view and not important views. The flag used here
+ * is legacy flag which will be replaced with soon.
*
* @hide
*/
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 508c20a..781a4b6 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -687,11 +687,11 @@
// If a package is fully denied, then all views that marked as not
// important for autofill will not trigger fill request
- private boolean mIsPackageFullyDeniedForAutofillForUnimportantView = false;
+ private boolean mIsPackageFullyDeniedForAutofill = false;
// If a package is partially denied, autofill manager will check whether
// current activity is in deny set to decide whether to trigger fill request
- private boolean mIsPackagePartiallyDeniedForAutofillForUnimportantView = false;
+ private boolean mIsPackagePartiallyDeniedForAutofill = false;
// A deny set read from device config
private Set<String> mDeniedActivitiySet = new ArraySet<>();
@@ -876,15 +876,15 @@
final String packageName = mContext.getPackageName();
- mIsPackageFullyDeniedForAutofillForUnimportantView =
- isPackageFullyDeniedForAutofillForUnimportantView(denyListString, packageName);
+ mIsPackageFullyDeniedForAutofill =
+ isPackageFullyDeniedForAutofill(denyListString, packageName);
- if (!mIsPackageFullyDeniedForAutofillForUnimportantView) {
- mIsPackagePartiallyDeniedForAutofillForUnimportantView =
- isPackagePartiallyDeniedForAutofillForUnimportantView(denyListString, packageName);
+ if (!mIsPackageFullyDeniedForAutofill) {
+ mIsPackagePartiallyDeniedForAutofill =
+ isPackagePartiallyDeniedForAutofill(denyListString, packageName);
}
- if (mIsPackagePartiallyDeniedForAutofillForUnimportantView) {
+ if (mIsPackagePartiallyDeniedForAutofill) {
setDeniedActivitySetWithDenyList(denyListString, packageName);
}
}
@@ -899,6 +899,15 @@
}
/**
+ * Whether to trigger fill request on not important views that passes heuristic check
+ *
+ * @hide
+ */
+ public boolean isTriggerFillRequestOnUnimportantViewEnabled() {
+ return mIsTriggerFillRequestOnUnimportantViewEnabled;
+ }
+
+ /**
* Whether view passes the imeAction check
*
* @hide
@@ -906,13 +915,13 @@
public boolean isPassingImeActionCheck(EditText editText) {
final int actionId = editText.getImeOptions();
if (mNonAutofillableImeActionIdSet.contains(String.valueOf(actionId))) {
- // TODO: add a log to indicate what has filtered out the view
+ Log.d(TAG, "view not autofillable - not passing ime action check");
return false;
}
return true;
}
- private boolean isPackageFullyDeniedForAutofillForUnimportantView(
+ private boolean isPackageFullyDeniedForAutofill(
@NonNull String denyListString, @NonNull String packageName) {
// If "PackageName:;" is in the string, then it means the package name is in denylist
// and there are no activities specified under it. That means the package is fully
@@ -920,7 +929,7 @@
return denyListString.indexOf(packageName + ":;") != -1;
}
- private boolean isPackagePartiallyDeniedForAutofillForUnimportantView(
+ private boolean isPackagePartiallyDeniedForAutofill(
@NonNull String denyListString, @NonNull String packageName) {
// This check happens after checking package is not fully denied. If "PackageName:" instead
// is in denylist, then it means there are specific activities to be denied. So the package
@@ -968,17 +977,16 @@
}
/**
- * Check whether autofill is denied for current activity or package. Used when a view is marked
- * as not important for autofill, if current activity or package is denied, then the view won't
- * trigger fill request.
+ * Check whether autofill is denied for current activity or package. If current activity or
+ * package is denied, then the view won't trigger fill request.
*
* @hide
*/
- public final boolean isActivityDeniedForAutofillForUnimportantView() {
- if (mIsPackageFullyDeniedForAutofillForUnimportantView) {
+ public boolean isActivityDeniedForAutofill() {
+ if (mIsPackageFullyDeniedForAutofill) {
return true;
}
- if (mIsPackagePartiallyDeniedForAutofillForUnimportantView) {
+ if (mIsPackagePartiallyDeniedForAutofill) {
final AutofillClient client = getClient();
if (client == null) {
return false;
@@ -992,27 +1000,36 @@
}
/**
- * Check whether view matches autofill-able heuristics
+ * Check heuristics and other rules to determine if view is autofillable
+ *
+ * Note: this function should be only called only when autofill for all apps is turned on. The
+ * calling method needs to check the corresponding flag to make sure that before calling into
+ * this function.
*
* @hide
*/
- public final boolean isMatchingAutofillableHeuristicsForNotImportantViews(@NonNull View view) {
- if (!mIsTriggerFillRequestOnUnimportantViewEnabled) {
+ public boolean isAutofillable(View view) {
+ if (isActivityDeniedForAutofill()) {
+ Log.d(TAG, "view is not autofillable - activity denied for autofill");
return false;
}
- // TODO: remove the autofill type check when this function is applied on both important and
- // not important views.
- // This check is needed here because once the view type check is lifted, addiditional
- // unimportant views will be added to the assist structure which may cuase system health
- // regression (viewGroup#populateChidlrenForAutofill() calls this function to decide whether
- // to include child view)
+ // Duplicate the autofill type check here because ViewGroup will call this function to
+ // decide whether to include view in assist structure.
+ // Also keep the autofill type check inside View#IsAutofillable() to serve as an early out
+ // or if other functions need to call it.
if (view.getAutofillType() == View.AUTOFILL_TYPE_NONE) return false;
if (view instanceof EditText) {
return isPassingImeActionCheck((EditText) view);
}
+ // Skip view type check if view is important for autofill or
+ // shouldEnableAutofillOnAllViewTypes flag is turned on
+ if (view.isImportantForAutofill() || mShouldEnableAutofillOnAllViewTypes) {
+ return true;
+ }
+
if (view instanceof CheckBox
|| view instanceof Spinner
|| view instanceof DatePicker
@@ -1021,10 +1038,9 @@
return true;
}
- return mShouldEnableAutofillOnAllViewTypes;
+ return false;
}
-
/**
* @hide
*/
diff --git a/core/java/android/view/inputmethod/HandwritingGesture.java b/core/java/android/view/inputmethod/HandwritingGesture.java
index e7207fa..c4d43bc 100644
--- a/core/java/android/view/inputmethod/HandwritingGesture.java
+++ b/core/java/android/view/inputmethod/HandwritingGesture.java
@@ -22,6 +22,7 @@
import android.annotation.TestApi;
import android.graphics.RectF;
import android.inputmethodservice.InputMethodService;
+import android.os.CancellationSignal;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.MotionEvent;
@@ -33,18 +34,20 @@
import java.util.function.IntConsumer;
/**
- * Base class for Stylus handwriting gesture.
- *
+ * Base class for stylus handwriting gestures.
+ * <p>
* During a stylus handwriting session, user can perform a stylus gesture operation like
* {@link SelectGesture}, {@link DeleteGesture}, {@link InsertGesture} on an
- * area of text. IME is responsible for listening to Stylus {@link MotionEvent} using
+ * area of text. IME is responsible for listening to stylus {@link MotionEvent}s using
* {@link InputMethodService#onStylusHandwritingMotionEvent} and interpret if it can translate to a
* gesture operation.
- * While creating Gesture operations {@link SelectGesture}, {@link DeleteGesture},
- * , {@code Granularity} helps pick the correct granular level of text like word level
+ * <p>
+ * While creating gesture operations {@link SelectGesture} and {@link DeleteGesture},
+ * {@code Granularity} helps pick the correct granular level of text like word level
* {@link #GRANULARITY_WORD}, or character level {@link #GRANULARITY_CHARACTER}.
*
* @see InputConnection#performHandwritingGesture(HandwritingGesture, Executor, IntConsumer)
+ * @see InputConnection#previewHandwritingGesture(PreviewableHandwritingGesture, CancellationSignal)
* @see InputMethodService#onStartStylusHandwriting()
*/
public abstract class HandwritingGesture {
diff --git a/core/java/android/webkit/HttpAuthHandler.java b/core/java/android/webkit/HttpAuthHandler.java
index 5353bc6..715fc9a 100644
--- a/core/java/android/webkit/HttpAuthHandler.java
+++ b/core/java/android/webkit/HttpAuthHandler.java
@@ -41,6 +41,9 @@
* are suitable for use. Credentials are not suitable if they have
* previously been rejected by the server for the current request.
*
+ * <p class="note"><b>Note:</b> The host application must call this method
+ * on the host application's UI Thread.
+ *
* @return whether the credentials are suitable for use
* @see WebView#getHttpAuthUsernamePassword
*/
@@ -50,6 +53,9 @@
/**
* Instructs the WebView to cancel the authentication request.
+ *
+ * <p class="note"><b>Note:</b> The host application must call this method
+ * on the host application's UI Thread.
*/
public void cancel() {
}
@@ -58,6 +64,9 @@
* Instructs the WebView to proceed with the authentication with the given
* credentials. Credentials for use with this method can be retrieved from
* the WebView's store using {@link WebView#getHttpAuthUsernamePassword}.
+ *
+ * <p class="note"><b>Note:</b> The host application must call this method
+ * on the host application's UI Thread.
*/
public void proceed(String username, String password) {
}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 7b6e1a3..55f09f1 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -455,6 +455,9 @@
* {@link HttpAuthHandler} to set the WebView's response to the request.
* The default behavior is to cancel the request.
*
+ * <p class="note"><b>Note:</b> The supplied HttpAuthHandler must be used on
+ * the UI thread.
+ *
* @param view the WebView that is initiating the callback
* @param handler the HttpAuthHandler used to set the WebView's response
* @param host the host requiring authentication
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index dce5432..088065d2 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3193,47 +3193,66 @@
menuItemOrderPasteAsPlainText = 11;
}
+ final TypedArray a = mTextView.getContext().obtainStyledAttributes(new int[] {
+ // TODO: Make Undo/Redo be public attribute.
+ com.android.internal.R.attr.actionModeUndoDrawable,
+ com.android.internal.R.attr.actionModeRedoDrawable,
+ android.R.attr.actionModeCutDrawable,
+ android.R.attr.actionModeCopyDrawable,
+ android.R.attr.actionModePasteDrawable,
+ android.R.attr.actionModeSelectAllDrawable,
+ android.R.attr.actionModeShareDrawable,
+ });
+
menu.add(CONTEXT_MENU_GROUP_UNDO_REDO, TextView.ID_UNDO, menuItemOrderUndo,
com.android.internal.R.string.undo)
.setAlphabeticShortcut('z')
.setOnMenuItemClickListener(mOnContextMenuItemClickListener)
+ .setIcon(a.getDrawable(0))
.setEnabled(mTextView.canUndo());
menu.add(CONTEXT_MENU_GROUP_UNDO_REDO, TextView.ID_REDO, menuItemOrderRedo,
com.android.internal.R.string.redo)
.setAlphabeticShortcut('z', KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)
.setOnMenuItemClickListener(mOnContextMenuItemClickListener)
+ .setIcon(a.getDrawable(1))
.setEnabled(mTextView.canRedo());
menu.add(CONTEXT_MENU_GROUP_CLIPBOARD, TextView.ID_CUT, menuItemOrderCut,
com.android.internal.R.string.cut)
.setAlphabeticShortcut('x')
.setOnMenuItemClickListener(mOnContextMenuItemClickListener)
+ .setIcon(a.getDrawable(2))
.setEnabled(mTextView.canCut());
menu.add(CONTEXT_MENU_GROUP_CLIPBOARD, TextView.ID_COPY, menuItemOrderCopy,
com.android.internal.R.string.copy)
.setAlphabeticShortcut('c')
.setOnMenuItemClickListener(mOnContextMenuItemClickListener)
+ .setIcon(a.getDrawable(3))
.setEnabled(mTextView.canCopy());
menu.add(CONTEXT_MENU_GROUP_CLIPBOARD, TextView.ID_PASTE, menuItemOrderPaste,
com.android.internal.R.string.paste)
.setAlphabeticShortcut('v')
.setEnabled(mTextView.canPaste())
+ .setIcon(a.getDrawable(4))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
menu.add(CONTEXT_MENU_GROUP_CLIPBOARD, TextView.ID_PASTE_AS_PLAIN_TEXT,
menuItemOrderPasteAsPlainText,
com.android.internal.R.string.paste_as_plain_text)
.setAlphabeticShortcut('v', KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)
.setEnabled(mTextView.canPasteAsPlainText())
+ .setIcon(a.getDrawable(4))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
menu.add(CONTEXT_MENU_GROUP_CLIPBOARD, TextView.ID_SELECT_ALL,
menuItemOrderSelectAll, com.android.internal.R.string.selectAll)
.setAlphabeticShortcut('a')
.setEnabled(mTextView.canSelectAllText())
+ .setIcon(a.getDrawable(5))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
menu.add(CONTEXT_MENU_GROUP_MISC, TextView.ID_SHARE, menuItemOrderShare,
com.android.internal.R.string.share)
.setEnabled(mTextView.canShare())
+ .setIcon(a.getDrawable(6))
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
menu.add(CONTEXT_MENU_GROUP_MISC, TextView.ID_AUTOFILL, menuItemOrderAutofill,
android.R.string.autofill)
@@ -3241,6 +3260,7 @@
.setOnMenuItemClickListener(mOnContextMenuItemClickListener);
mPreserveSelection = true;
+ a.recycle();
// No-op for the old context menu because it doesn't have icons.
adjustIconSpacing(menu);
diff --git a/core/java/android/window/WindowMetricsController.java b/core/java/android/window/WindowMetricsController.java
index 3478b0f..954f686 100644
--- a/core/java/android/window/WindowMetricsController.java
+++ b/core/java/android/window/WindowMetricsController.java
@@ -54,9 +54,6 @@
* @hide
*/
public final class WindowMetricsController {
- // TODO(b/151908239): Remove and always enable this if it is stable.
- private static final boolean LAZY_WINDOW_INSETS = android.os.SystemProperties.getBoolean(
- "persist.wm.debug.win_metrics_lazy_insets", true);
private final Context mContext;
public WindowMetricsController(@NonNull Context context) {
@@ -98,9 +95,7 @@
final IBinder token = Context.getToken(mContext);
final Supplier<WindowInsets> insetsSupplier = () -> getWindowInsetsFromServerForDisplay(
mContext.getDisplayId(), token, bounds, isScreenRound, windowingMode);
- return LAZY_WINDOW_INSETS
- ? new WindowMetrics(new Rect(bounds), insetsSupplier, density)
- : new WindowMetrics(new Rect(bounds), insetsSupplier.get(), density);
+ return new WindowMetrics(new Rect(bounds), insetsSupplier, density);
}
/**
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index ae192a4..75e797b 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -16,14 +16,17 @@
package com.android.internal.app;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL;
import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK;
import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.app.ResolverActivity.EXTRA_CALLING_USER;
import static com.android.internal.app.ResolverActivity.EXTRA_SELECTED_PROFILE;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.AppGlobals;
@@ -79,6 +82,10 @@
public static String FORWARD_INTENT_TO_MANAGED_PROFILE
= "com.android.internal.app.ForwardIntentToManagedProfile";
+ @TestApi
+ public static final String EXTRA_SKIP_USER_CONFIRMATION =
+ "com.android.internal.app.EXTRA_SKIP_USER_CONFIRMATION";
+
private static final Set<String> ALLOWED_TEXT_MESSAGE_SCHEMES
= new HashSet<>(Arrays.asList("sms", "smsto", "mms", "mmsto"));
@@ -181,6 +188,15 @@
return;
}
+ if (launchIntent.getBooleanExtra(EXTRA_SKIP_USER_CONFIRMATION, /* defaultValue= */ false)
+ && getCallingPackage() != null
+ && PERMISSION_GRANTED == getPackageManager().checkPermission(
+ INTERACT_ACROSS_USERS, getCallingPackage())) {
+ startActivityAsCaller(launchIntent, targetUserId);
+ finish();
+ return;
+ }
+
int layoutId = R.layout.miniresolver;
setContentView(layoutId);
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 0d02683..a1d571f 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -1,4 +1,6 @@
per-file *AppOp* = file:/core/java/android/permission/OWNERS
+per-file UnlaunchableAppActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
+per-file IntentForwarderActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
per-file *Resolver* = file:/packages/SystemUI/OWNERS
per-file *Chooser* = file:/packages/SystemUI/OWNERS
per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
diff --git a/core/java/com/android/internal/expresslog/Histogram.java b/core/java/com/android/internal/expresslog/Histogram.java
index 2f3b662..65fbb03 100644
--- a/core/java/com/android/internal/expresslog/Histogram.java
+++ b/core/java/com/android/internal/expresslog/Histogram.java
@@ -16,10 +16,14 @@
package com.android.internal.expresslog;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import com.android.internal.util.FrameworkStatsLog;
+import java.util.Arrays;
+
/** Histogram encapsulates StatsD write API calls */
public final class Histogram {
@@ -28,7 +32,8 @@
/**
* Creates Histogram metric logging wrapper
- * @param metricId to log, logging will be no-op if metricId is not defined in the TeX catalog
+ *
+ * @param metricId to log, logging will be no-op if metricId is not defined in the TeX catalog
* @param binOptions to calculate bin index for samples
* @hide
*/
@@ -39,6 +44,7 @@
/**
* Logs increment sample count for automatically calculated bin
+ *
* @param sample value
* @hide
*/
@@ -52,6 +58,7 @@
public interface BinOptions {
/**
* Returns bins count to be used by a histogram
+ *
* @return bins count used to initialize Options, including overflow & underflow bins
* @hide
*/
@@ -61,6 +68,7 @@
* Returns bin index for the input sample value
* index == 0 stands for underflow
* index == getBinsCount() - 1 stands for overflow
+ *
* @return zero based index
* @hide
*/
@@ -76,17 +84,19 @@
private final float mBinSize;
/**
- * Creates otpions for uniform (linear) sized bins
- * @param binCount amount of histogram bins. 2 bin indexes will be calculated
- * automatically to represent undeflow & overflow bins
- * @param minValue is included in the first bin, values less than minValue
- * go to underflow bin
+ * Creates options for uniform (linear) sized bins
+ *
+ * @param binCount amount of histogram bins. 2 bin indexes will be calculated
+ * automatically to represent underflow & overflow bins
+ * @param minValue is included in the first bin, values less than minValue
+ * go to underflow bin
* @param exclusiveMaxValue is included in the overflow bucket. For accurate
- measure up to kMax, then exclusiveMaxValue
+ * measure up to kMax, then exclusiveMaxValue
* should be set to kMax + 1
* @hide
*/
- public UniformOptions(int binCount, float minValue, float exclusiveMaxValue) {
+ public UniformOptions(@IntRange(from = 1) int binCount, float minValue,
+ float exclusiveMaxValue) {
if (binCount < 1) {
throw new IllegalArgumentException("Bin count should be positive number");
}
@@ -99,7 +109,7 @@
mExclusiveMaxValue = exclusiveMaxValue;
mBinSize = (mExclusiveMaxValue - minValue) / binCount;
- // Implicitly add 2 for the extra undeflow & overflow bins
+ // Implicitly add 2 for the extra underflow & overflow bins
mBinCount = binCount + 2;
}
@@ -120,4 +130,92 @@
return (int) ((sample - mMinValue) / mBinSize + 1);
}
}
+
+ /** Used by Histogram to map data sample to corresponding bin for scaled bins */
+ public static final class ScaledRangeOptions implements BinOptions {
+ // store minimum value per bin
+ final long[] mBins;
+
+ /**
+ * Creates options for scaled range bins
+ *
+ * @param binCount amount of histogram bins. 2 bin indexes will be calculated
+ * automatically to represent underflow & overflow bins
+ * @param minValue is included in the first bin, values less than minValue
+ * go to underflow bin
+ * @param firstBinWidth used to represent first bin width and as a reference to calculate
+ * width for consecutive bins
+ * @param scaleFactor used to calculate width for consecutive bins
+ * @hide
+ */
+ public ScaledRangeOptions(@IntRange(from = 1) int binCount, int minValue,
+ @FloatRange(from = 1.f) float firstBinWidth,
+ @FloatRange(from = 1.f) float scaleFactor) {
+ if (binCount < 1) {
+ throw new IllegalArgumentException("Bin count should be positive number");
+ }
+
+ if (firstBinWidth < 1.f) {
+ throw new IllegalArgumentException(
+ "First bin width invalid (should be 1.f at minimum)");
+ }
+
+ if (scaleFactor < 1.f) {
+ throw new IllegalArgumentException(
+ "Scaled factor invalid (should be 1.f at minimum)");
+ }
+
+ // precalculating bins ranges (no need to create a bin for underflow reference value)
+ mBins = initBins(binCount + 1, minValue, firstBinWidth, scaleFactor);
+ }
+
+ @Override
+ public int getBinsCount() {
+ return mBins.length + 1;
+ }
+
+ @Override
+ public int getBinForSample(float sample) {
+ if (sample < mBins[0]) {
+ // goes to underflow
+ return 0;
+ } else if (sample >= mBins[mBins.length - 1]) {
+ // goes to overflow
+ return mBins.length;
+ }
+
+ return lower_bound(mBins, (long) sample) + 1;
+ }
+
+ // To find lower bound using binary search implementation of Arrays utility class
+ private static int lower_bound(long[] array, long sample) {
+ int index = Arrays.binarySearch(array, sample);
+ // If key is not present in the array
+ if (index < 0) {
+ // Index specify the position of the key when inserted in the sorted array
+ // so the element currently present at this position will be the lower bound
+ return Math.abs(index) - 2;
+ }
+ return index;
+ }
+
+ private static long[] initBins(int count, int minValue, float firstBinWidth,
+ float scaleFactor) {
+ long[] bins = new long[count];
+ bins[0] = minValue;
+ double lastWidth = firstBinWidth;
+ for (int i = 1; i < count; i++) {
+ // current bin minValue = previous bin width * scaleFactor
+ double currentBinMinValue = bins[i - 1] + lastWidth;
+ if (currentBinMinValue > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException(
+ "Attempted to create a bucket larger than maxint");
+ }
+
+ bins[i] = (long) currentBinMinValue;
+ lastWidth *= scaleFactor;
+ }
+ return bins;
+ }
+ }
}
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 5cab674..1172f7b 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -1297,6 +1297,17 @@
return set;
}
+ /** Sets the default attributes of the screenshot layer used for animation. */
+ public static void configureScreenshotLayer(SurfaceControl.Transaction t, SurfaceControl layer,
+ ScreenCapture.ScreenshotHardwareBuffer buffer) {
+ t.setBuffer(layer, buffer.getHardwareBuffer());
+ t.setDataSpace(layer, buffer.getColorSpace().getDataSpace());
+ // Avoid showing dimming effect for HDR content when running animation.
+ if (buffer.containsHdrLayers()) {
+ t.setDimmingEnabled(layer, false);
+ }
+ }
+
/** Returns whether the hardware buffer passed in is marked as protected. */
public static boolean hasProtectedContent(HardwareBuffer hardwareBuffer) {
return (hardwareBuffer.getUsage() & HardwareBuffer.USAGE_PROTECTED_CONTENT)
diff --git a/core/java/com/android/internal/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java
index ad1fdba..ec525f0 100644
--- a/core/java/com/android/internal/protolog/ProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java
@@ -85,7 +85,7 @@
Consts.TAG_WM),
WM_DEBUG_WINDOW_INSETS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM),
- WM_DEBUG_CONTENT_RECORDING(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ WM_DEBUG_CONTENT_RECORDING(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
Consts.TAG_WM),
WM_DEBUG_WALLPAPER(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
WM_DEBUG_BACK_PREVIEW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index bd85874..bce53328 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -5,6 +5,9 @@
# Connectivity
per-file android_net_* = codewiz@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
+# Choreographer
+per-file android_view_DisplayEventReceiver* = file:platform/frameworks/native:/services/surfaceflinger/OWNERS
+
# CPU
per-file *Cpu* = file:/core/java/com/android/internal/os/CPU_OWNERS
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index d62f1cf..ce806a0 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -2296,7 +2296,9 @@
// region shared with the child process we reduce the number of pages that
// transition to the private-dirty state when malloc adjusts the meta-data
// on each of the pages it is managing after the fork.
- mallopt(M_PURGE, 0);
+ if (mallopt(M_PURGE_ALL, 0) != 1) {
+ mallopt(M_PURGE, 0);
+ }
}
pid_t pid = fork();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0f1e558..12106c7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -821,6 +821,7 @@
<protected-broadcast android:name="android.intent.action.PROFILE_REMOVED" />
<protected-broadcast android:name="com.android.internal.telephony.cat.SMS_SENT_ACTION" />
<protected-broadcast android:name="com.android.internal.telephony.cat.SMS_DELIVERY_ACTION" />
+ <protected-broadcast android:name="com.android.internal.telephony.data.ACTION_RETRY" />
<protected-broadcast android:name="android.companion.virtual.action.VIRTUAL_DEVICE_REMOVED" />
<protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_START_PREVIEW" />
<protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_STOP_PREVIEW" />
@@ -4493,6 +4494,12 @@
<permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ORIGIN"
android:protectionLevel="normal" />
+ <!-- Allows a browser to invoke the set of query apis to get metadata about credential
+ candidates prepared during the CredentialManager.prepareGetCredential API.
+ <p>Protection level: normal -->
+ <permission android:name="android.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS"
+ android:protectionLevel="normal" />
+
<!-- Allows permission to use Credential Manager UI for providing and saving credentials
@hide -->
<permission android:name="android.permission.LAUNCH_CREDENTIAL_SELECTOR"
diff --git a/core/res/TEST_MAPPING b/core/res/TEST_MAPPING
index 9185bae..4d09076 100644
--- a/core/res/TEST_MAPPING
+++ b/core/res/TEST_MAPPING
@@ -1,13 +1,13 @@
{
"presubmit": [
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.PermissionPolicyTest#platformPermissionPolicyIsUnaltered"
+ "include-filter": "android.permissionpolicy.cts.PermissionPolicyTest#platformPermissionPolicyIsUnaltered"
},
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
}
diff --git a/core/res/res/drawable/accessibility_magnification_thumbnail_background_bg.xml b/core/res/res/drawable/accessibility_magnification_thumbnail_background_bg.xml
index 7b82b4d..bb6dc46 100644
--- a/core/res/res/drawable/accessibility_magnification_thumbnail_background_bg.xml
+++ b/core/res/res/drawable/accessibility_magnification_thumbnail_background_bg.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-<item>
+ <item>
<shape android:shape="rectangle">
- <stroke
- android:width="1dp"
- android:color="@color/accessibility_magnification_thumbnail_stroke_color" />
- <corners android:radius="4dp"/>
- <solid android:color="@color/accessibility_magnification_thumbnail_background_color" />
+ <stroke
+ android:width="@dimen/accessibility_magnification_thumbnail_container_stroke_width"
+ android:color="@color/accessibility_magnification_thumbnail_container_stroke_color" />
+ <corners android:radius="8dp"/>
+ <solid android:color="@color/accessibility_magnification_thumbnail_container_background_color" />
</shape>
-</item>
+ </item>
</layer-list>
diff --git a/core/res/res/drawable/accessibility_magnification_thumbnail_background_fg.xml b/core/res/res/drawable/accessibility_magnification_thumbnail_background_fg.xml
new file mode 100644
index 0000000..ef77b34
--- /dev/null
+++ b/core/res/res/drawable/accessibility_magnification_thumbnail_background_fg.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <!-- We draw the border as a foreground too so the thumbnail doesn't encroach and overlap
+ the rounded corners.
+ We also draw it on the background, otherwise you can see a tiny bit of the black fill
+ poking out around the white border. -->
+ <stroke
+ android:width="@dimen/accessibility_magnification_thumbnail_container_stroke_width"
+ android:color="@color/accessibility_magnification_thumbnail_container_stroke_color" />
+ <corners android:radius="8dp"/>
+ </shape>
+ </item>
+</layer-list>
diff --git a/core/res/res/drawable/accessibility_magnification_thumbnail_bg.xml b/core/res/res/drawable/accessibility_magnification_thumbnail_bg.xml
index 77ba94e..cf0aee5 100644
--- a/core/res/res/drawable/accessibility_magnification_thumbnail_bg.xml
+++ b/core/res/res/drawable/accessibility_magnification_thumbnail_bg.xml
@@ -14,10 +14,13 @@
limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-<item>
+ <item>
<shape android:shape="rectangle">
- <corners android:radius="2dp"/>
- <solid android:color="@color/accessibility_magnification_thumbnail_color" />
+ <stroke
+ android:width="2dp"
+ android:color="@color/accessibility_magnification_thumbnail_stroke_color" />
+ <corners android:radius="2dp"/>
+ <solid android:color="@color/accessibility_magnification_thumbnail_background_color" />
</shape>
-</item>
+ </item>
</layer-list>
diff --git a/core/res/res/drawable/ic_menu_redo_material.xml b/core/res/res/drawable/ic_menu_redo_material.xml
new file mode 100644
index 0000000..28e6733
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_redo_material.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2023 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="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M9.9,19Q7.475,19 5.738,17.425Q4,15.85 4,13.5Q4,11.15 5.738,9.575Q7.475,8 9.9,8H16.2L13.6,5.4L15,4L20,9L15,14L13.6,12.6L16.2,10H9.9Q8.325,10 7.163,11Q6,12 6,13.5Q6,15 7.163,16Q8.325,17 9.9,17H17V19Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_menu_undo_material.xml b/core/res/res/drawable/ic_menu_undo_material.xml
new file mode 100644
index 0000000..8e05a52
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_undo_material.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2023 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="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14.1,19H7V17H14.1Q15.675,17 16.837,16Q18,15 18,13.5Q18,12 16.837,11Q15.675,10 14.1,10H7.8L10.4,12.6L9,14L4,9L9,4L10.4,5.4L7.8,8H14.1Q16.525,8 18.263,9.575Q20,11.15 20,13.5Q20,15.85 18.263,17.425Q16.525,19 14.1,19Z"/>
+</vector>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 16a8bb7..710a70a 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -116,7 +116,8 @@
<com.android.internal.widget.NotificationVanishingFrameLayout
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_headerless_line_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_headerless_line_height"
>
<!-- This is the simplest way to keep this text vertically centered without
gravity="center_vertical" which causes jumpiness in expansion animations. -->
diff --git a/core/res/res/layout/thumbnail_background_view.xml b/core/res/res/layout/thumbnail_background_view.xml
index 0ba01e9..423af83 100644
--- a/core/res/res/layout/thumbnail_background_view.xml
+++ b/core/res/res/layout/thumbnail_background_view.xml
@@ -16,8 +16,12 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/accessibility_magnification_thumbnail_background_bg">
+ android:background="@drawable/accessibility_magnification_thumbnail_background_bg"
+ android:foreground="@drawable/accessibility_magnification_thumbnail_background_fg"
+ android:padding="@dimen/accessibility_magnification_thumbnail_container_stroke_width"
+>
<View
+ android:padding="@dimen/accessibility_magnification_thumbnail_container_stroke_width"
android:id="@+id/accessibility_magnification_thumbnail_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b53502d..cd25726 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -918,6 +918,10 @@
<attr name="actionModeFindDrawable" format="reference" />
<!-- Drawable to use for the Web Search action button in WebView selection action modes. -->
<attr name="actionModeWebSearchDrawable" format="reference" />
+ <!-- Drawable to use for the Undo action button in WebView selection action modes. -->
+ <attr name="actionModeUndoDrawable" format="reference" />
+ <!-- Drawable to use for the Redo action button in WebView selection action modes. -->
+ <attr name="actionModeRedoDrawable" format="reference" />
<!-- PopupWindow style to use for action modes when showing as a window overlay. -->
<attr name="actionModePopupWindowStyle" format="reference" />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index dc75658..e67ea82 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -470,18 +470,18 @@
<color name="system_on_error_light">#FFFFFF</color>
<color name="system_error_container_light">#FFDAD5</color>
<color name="system_on_error_container_light">#410000</color>
- <color name="system_primary_fixed_light">#D8E2FF</color>
- <color name="system_primary_fixed_dim_light">#ADC6FF</color>
- <color name="system_on_primary_fixed_light">#001A41</color>
- <color name="system_on_primary_fixed_variant_light">#2B4678</color>
- <color name="system_secondary_fixed_light">#DBE2F9</color>
- <color name="system_secondary_fixed_dim_light">#BFC6DC</color>
- <color name="system_on_secondary_fixed_light">#141B2C</color>
- <color name="system_on_secondary_fixed_variant_light">#3F4759</color>
- <color name="system_tertiary_fixed_light">#FBD7FC</color>
- <color name="system_tertiary_fixed_dim_light">#DEBCDF</color>
- <color name="system_on_tertiary_fixed_light">#29132D</color>
- <color name="system_on_tertiary_fixed_variant_light">#583E5B</color>
+ <color name="system_primary_fixed">#D8E2FF</color>
+ <color name="system_primary_fixed_dim">#ADC6FF</color>
+ <color name="system_on_primary_fixed">#001A41</color>
+ <color name="system_on_primary_fixed_variant">#2B4678</color>
+ <color name="system_secondary_fixed">#DBE2F9</color>
+ <color name="system_secondary_fixed_dim">#BFC6DC</color>
+ <color name="system_on_secondary_fixed">#141B2C</color>
+ <color name="system_on_secondary_fixed_variant">#3F4759</color>
+ <color name="system_tertiary_fixed">#FBD7FC</color>
+ <color name="system_tertiary_fixed_dim">#DEBCDF</color>
+ <color name="system_on_tertiary_fixed">#29132D</color>
+ <color name="system_on_tertiary_fixed_variant">#583E5B</color>
<color name="system_control_activated_light">#D8E2FF</color>
<color name="system_control_normal_light">#44474F</color>
<color name="system_control_highlight_light">#1F000000</color>
@@ -526,18 +526,6 @@
<color name="system_on_error_dark">#690001</color>
<color name="system_error_container_dark">#930001</color>
<color name="system_on_error_container_dark">#FFDAD5</color>
- <color name="system_primary_fixed_dark">#D8E2FF</color>
- <color name="system_primary_fixed_dim_dark">#ADC6FF</color>
- <color name="system_on_primary_fixed_dark">#001A41</color>
- <color name="system_on_primary_fixed_variant_dark">#2B4678</color>
- <color name="system_secondary_fixed_dark">#DBE2F9</color>
- <color name="system_secondary_fixed_dim_dark">#BFC6DC</color>
- <color name="system_on_secondary_fixed_dark">#141B2C</color>
- <color name="system_on_secondary_fixed_variant_dark">#3F4759</color>
- <color name="system_tertiary_fixed_dark">#FBD7FC</color>
- <color name="system_tertiary_fixed_dim_dark">#DEBCDF</color>
- <color name="system_on_tertiary_fixed_dark">#29132D</color>
- <color name="system_on_tertiary_fixed_variant_dark">#583E5B</color>
<color name="system_control_activated_dark">#2B4678</color>
<color name="system_control_normal_dark">#C4C6D0</color>
<color name="system_control_highlight_dark">#33FFFFFF</color>
@@ -559,9 +547,10 @@
<color name="accessibility_color_inversion_background">#546E7A</color>
<!-- Fullscreen magnification thumbnail color -->
- <color name="accessibility_magnification_thumbnail_stroke_color">#E0E0E0</color>
- <color name="accessibility_magnification_thumbnail_background_color">#FCFCFC</color>
- <color name="accessibility_magnification_thumbnail_color">#252525</color>
+ <color name="accessibility_magnification_thumbnail_stroke_color">#0C0C0C</color>
+ <color name="accessibility_magnification_thumbnail_background_color">#B3FFFFFF</color>
+ <color name="accessibility_magnification_thumbnail_container_background_color">#99000000</color>
+ <color name="accessibility_magnification_thumbnail_container_stroke_color">#FFFFFF</color>
<!-- Color of camera light when camera is in use -->
<color name="camera_privacy_light_day">#FFFFFF</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 19fa7a3..0600b380 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -755,6 +755,11 @@
we rely on gravity to determine the effective orientation. -->
<bool name="config_deskDockEnablesAccelerometer">true</bool>
+ <!-- Control whether nosensor and locked orientation requests are respected from the app when
+ config_deskDockEnablesAccelerometer is set to false.
+ TODO(b/274763533): Consider making true by default and removing this. -->
+ <bool name="config_deskRespectsNoSensorAndLockedWithoutAccelerometer">false</bool>
+
<!-- Car dock behavior -->
<!-- The number of degrees to rotate the display when the device is in a car dock.
@@ -5498,6 +5503,10 @@
<!-- Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps. -->
<bool name="config_letterboxIsVerticalReachabilityEnabled">false</bool>
+ <!-- Whether book mode automatic horizontal reachability positioning is allowed for letterboxed
+ fullscreen apps -->
+ <bool name="config_letterboxIsAutomaticReachabilityInBookModeEnabled">false</bool>
+
<!-- Default horizontal position of the letterboxed app window when reachability is
enabled and an app is fullscreen in landscape device orientation. When reachability is
enabled, the position can change between left, center and right. This config defines the
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index c0f2157..fab7609 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -62,6 +62,11 @@
<integer name="auto_data_switch_validation_max_retry">7</integer>
<java-symbol type="integer" name="auto_data_switch_validation_max_retry" />
+ <!-- Boolean indicating whether ping test is required to pass on the target data SIM before the
+ device automatically switch to it. -->
+ <bool name="auto_data_switch_ping_test_before_switch">true</bool>
+ <java-symbol type="bool" name="auto_data_switch_ping_test_before_switch" />
+
<!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
tunnels across service restart. If iwlan tunnels are not persisted across restart,
Framework will clean up dangling data connections when service restarts -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 80bf795..b1b1edf 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -356,7 +356,7 @@
<dimen name="notification_headerless_margin_twoline">20dp</dimen>
<!-- The height of each of the 1 or 2 lines in the headerless notification template -->
- <dimen name="notification_headerless_line_height">24sp</dimen>
+ <dimen name="notification_headerless_line_height">24dp</dimen>
<!-- vertical margin for the headerless notification content -->
<dimen name="notification_headerless_min_height">56dp</dimen>
@@ -609,6 +609,9 @@
<!-- padding of fullscreen magnification thumbnail -->
<dimen name="accessibility_magnification_thumbnail_padding">12dp</dimen>
+ <!-- width of the border of the magnification thumbnail -->
+ <dimen name="accessibility_magnification_thumbnail_container_stroke_width">4dp</dimen>
+
<!-- The padding ratio of the Accessibility icon foreground drawable -->
<item name="accessibility_icon_foreground_padding_ratio" type="dimen">21.88%</item>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 12a6c52..9cbf3b6 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -191,18 +191,18 @@
<public name="system_on_error_light" />
<public name="system_error_container_light" />
<public name="system_on_error_container_light" />
- <public name="system_primary_fixed_light" />
- <public name="system_primary_fixed_dim_light" />
- <public name="system_on_primary_fixed_light" />
- <public name="system_on_primary_fixed_variant_light" />
- <public name="system_secondary_fixed_light" />
- <public name="system_secondary_fixed_dim_light" />
- <public name="system_on_secondary_fixed_light" />
- <public name="system_on_secondary_fixed_variant_light" />
- <public name="system_tertiary_fixed_light" />
- <public name="system_tertiary_fixed_dim_light" />
- <public name="system_on_tertiary_fixed_light" />
- <public name="system_on_tertiary_fixed_variant_light" />
+ <public name="removed_system_primary_fixed_light" />
+ <public name="removed_system_primary_fixed_dim_light" />
+ <public name="removed_system_on_primary_fixed_light" />
+ <public name="removed_system_on_primary_fixed_variant_light" />
+ <public name="removed_system_secondary_fixed_light" />
+ <public name="removed_system_secondary_fixed_dim_light" />
+ <public name="removed_system_on_secondary_fixed_light" />
+ <public name="removed_system_on_secondary_fixed_variant_light" />
+ <public name="removed_system_tertiary_fixed_light" />
+ <public name="removed_system_tertiary_fixed_dim_light" />
+ <public name="removed_system_on_tertiary_fixed_light" />
+ <public name="removed_system_on_tertiary_fixed_variant_light" />
<public name="system_control_activated_light" />
<public name="system_control_normal_light" />
<public name="system_control_highlight_light" />
@@ -246,18 +246,18 @@
<public name="system_on_error_dark"/>
<public name="system_error_container_dark"/>
<public name="system_on_error_container_dark"/>
- <public name="system_primary_fixed_dark"/>
- <public name="system_primary_fixed_dim_dark"/>
- <public name="system_on_primary_fixed_dark"/>
- <public name="system_on_primary_fixed_variant_dark"/>
- <public name="system_secondary_fixed_dark"/>
- <public name="system_secondary_fixed_dim_dark"/>
- <public name="system_on_secondary_fixed_dark"/>
- <public name="system_on_secondary_fixed_variant_dark"/>
- <public name="system_tertiary_fixed_dark"/>
- <public name="system_tertiary_fixed_dim_dark"/>
- <public name="system_on_tertiary_fixed_dark"/>
- <public name="system_on_tertiary_fixed_variant_dark"/>
+ <public name="removed_system_primary_fixed_dark"/>
+ <public name="removed_system_primary_fixed_dim_dark"/>
+ <public name="removed_system_on_primary_fixed_dark"/>
+ <public name="removed_system_on_primary_fixed_variant_dark"/>
+ <public name="removed_system_secondary_fixed_dark"/>
+ <public name="removed_system_secondary_fixed_dim_dark"/>
+ <public name="removed_system_on_secondary_fixed_dark"/>
+ <public name="removed_system_on_secondary_fixed_variant_dark"/>
+ <public name="removed_system_tertiary_fixed_dark"/>
+ <public name="removed_system_tertiary_fixed_dim_dark"/>
+ <public name="removed_system_on_tertiary_fixed_dark"/>
+ <public name="removed_system_on_tertiary_fixed_variant_dark"/>
<public name="system_control_activated_dark"/>
<public name="system_control_normal_dark"/>
<public name="system_control_highlight_dark"/>
@@ -271,6 +271,18 @@
<public name="system_palette_key_color_tertiary_dark"/>
<public name="system_palette_key_color_neutral_dark"/>
<public name="system_palette_key_color_neutral_variant_dark"/>
+ <public name="system_primary_fixed" />
+ <public name="system_primary_fixed_dim" />
+ <public name="system_on_primary_fixed" />
+ <public name="system_on_primary_fixed_variant" />
+ <public name="system_secondary_fixed" />
+ <public name="system_secondary_fixed_dim" />
+ <public name="system_on_secondary_fixed" />
+ <public name="system_on_secondary_fixed_variant" />
+ <public name="system_tertiary_fixed" />
+ <public name="system_tertiary_fixed_dim" />
+ <public name="system_on_tertiary_fixed" />
+ <public name="system_on_tertiary_fixed_variant" />
<public name="system_outline_variant_light" />
<public name="system_outline_variant_dark" />
</staging-public-group>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 251db6d..53e2b3a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1692,6 +1692,7 @@
<java-symbol type="bool" name="config_carDockEnablesAccelerometer" />
<java-symbol type="bool" name="config_customUserSwitchUi" />
<java-symbol type="bool" name="config_deskDockEnablesAccelerometer" />
+ <java-symbol type="bool" name="config_deskRespectsNoSensorAndLockedWithoutAccelerometer" />
<java-symbol type="bool" name="config_disableMenuKeyInLockScreen" />
<java-symbol type="bool" name="config_enableCarDockHomeLaunch" />
<java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" />
@@ -4487,6 +4488,7 @@
<java-symbol type="dimen" name="config_letterboxTabletopModePositionMultiplier" />
<java-symbol type="bool" name="config_letterboxIsHorizontalReachabilityEnabled" />
<java-symbol type="bool" name="config_letterboxIsVerticalReachabilityEnabled" />
+ <java-symbol type="bool" name="config_letterboxIsAutomaticReachabilityInBookModeEnabled" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForHorizontalReachability" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForBookModeReachability" />
@@ -4514,10 +4516,13 @@
<!-- FullScreenMagnification thumbnail -->
<java-symbol type="layout" name="thumbnail_background_view" />
<java-symbol type="drawable" name="accessibility_magnification_thumbnail_background_bg" />
+ <java-symbol type="drawable" name="accessibility_magnification_thumbnail_background_fg" />
<java-symbol type="drawable" name="accessibility_magnification_thumbnail_bg" />
<java-symbol type="color" name="accessibility_magnification_thumbnail_stroke_color" />
<java-symbol type="color" name="accessibility_magnification_thumbnail_background_color" />
- <java-symbol type="color" name="accessibility_magnification_thumbnail_color" />
+ <java-symbol type="color" name="accessibility_magnification_thumbnail_container_background_color" />
+ <java-symbol type="color" name="accessibility_magnification_thumbnail_container_stroke_color" />
+ <java-symbol type="dimen" name="accessibility_magnification_thumbnail_container_stroke_width" />
<java-symbol type="dimen" name="accessibility_magnification_thumbnail_padding" />
<java-symbol type="id" name="accessibility_magnification_thumbnail_view" />
<!-- Package with global data query permissions for AppSearch -->
@@ -4986,8 +4991,7 @@
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
-
-
+
<java-symbol name="materialColorOnSecondaryFixedVariant" type="attr"/>
<java-symbol name="materialColorOnTertiaryFixedVariant" type="attr"/>
<java-symbol name="materialColorSurfaceContainerLowest" type="attr"/>
@@ -5033,4 +5037,6 @@
<java-symbol name="materialColorSurfaceContainer" type="attr"/>
<java-symbol name="materialColorSurfaceContainer" type="attr"/>
+ <java-symbol type="attr" name="actionModeUndoDrawable" />
+ <java-symbol type="attr" name="actionModeRedoDrawable" />
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index e96de582..bdbf96b 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -358,6 +358,8 @@
<item name="actionModeShareDrawable">@drawable/ic_menu_share_holo_dark</item>
<item name="actionModeFindDrawable">@drawable/ic_menu_find_holo_dark</item>
<item name="actionModeWebSearchDrawable">@drawable/ic_menu_search</item>
+ <item name="actionModeUndoDrawable">@drawable/ic_menu_undo_material</item>
+ <item name="actionModeRedoDrawable">@drawable/ic_menu_redo_material</item>
<item name="actionBarTabStyle">@style/Widget.ActionBar.TabView</item>
<item name="actionBarTabBarStyle">@style/Widget.ActionBar.TabBar</item>
<item name="actionBarTabTextStyle">@style/Widget.ActionBar.TabText</item>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 2986bdf..2e3d145 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -239,33 +239,33 @@
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -282,7 +282,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -335,33 +334,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -378,7 +377,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -430,33 +428,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -473,7 +471,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -527,33 +524,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -570,7 +567,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -623,33 +619,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -666,7 +662,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -727,33 +722,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -770,7 +765,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -822,33 +816,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -865,7 +859,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -916,33 +909,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -959,7 +952,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1011,33 +1003,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1054,7 +1046,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1122,33 +1113,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1165,7 +1156,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1218,33 +1208,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1261,7 +1251,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1312,33 +1301,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1355,7 +1344,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1408,33 +1396,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1451,7 +1439,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1503,33 +1490,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1546,7 +1533,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1598,33 +1584,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1641,7 +1627,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1693,33 +1678,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1736,7 +1721,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1788,33 +1772,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1831,7 +1815,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1883,33 +1866,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -1926,7 +1909,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -1983,33 +1965,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -2026,7 +2008,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -2076,33 +2057,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -2119,7 +2100,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -2307,33 +2287,33 @@
<item name="colorPopupBackground">?attr/colorBackgroundFloating</item>
<item name="panelColorBackground">?attr/colorBackgroundFloating</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2402,33 +2382,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2496,33 +2476,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2591,33 +2571,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2688,33 +2668,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2784,33 +2764,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2886,33 +2866,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -2984,33 +2964,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3081,33 +3061,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3179,33 +3159,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3258,33 +3238,33 @@
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3337,33 +3317,33 @@
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3435,33 +3415,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3534,33 +3514,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3631,33 +3611,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3727,33 +3707,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3822,33 +3802,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -3917,33 +3897,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -4010,33 +3990,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -4110,33 +4090,33 @@
<item name="colorListDivider">@color/list_divider_color_light</item>
<item name="opacityListDivider">@color/list_divider_opacity_device_default_light</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4153,7 +4133,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4191,33 +4170,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4234,7 +4213,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4264,33 +4242,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4307,7 +4285,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4359,33 +4336,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4402,7 +4379,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4438,33 +4414,33 @@
<!-- Dialog attributes -->
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4481,7 +4457,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4557,33 +4532,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4600,7 +4575,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4654,33 +4628,33 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4697,7 +4671,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4777,33 +4750,33 @@
<item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
<item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4820,7 +4793,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4830,33 +4802,33 @@
<item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
<item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -4887,33 +4859,33 @@
<item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
<item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -4930,7 +4902,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
@@ -4940,33 +4911,33 @@
<item name="layout_gravity">center</item>
<item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_light</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_light</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_light</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_light</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_light</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_light</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_light</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_light</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item>
<item name="materialColorErrorContainer">@color/system_error_container_light</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_light</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_light</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_light</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_light</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_light</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_light</item>
<item name="materialColorOnBackground">@color/system_on_background_light</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_light</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_light</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
@@ -5004,33 +4975,33 @@
<item name="textColorPrimary">@color/system_neutral1_900</item>
<item name="textColorSecondary">@color/system_neutral2_700</item>
- <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant_dark</item>
- <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant_dark</item>
+ <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
+ <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
<item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item>
- <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant_dark</item>
+ <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item>
<item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item>
<item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item>
<item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item>
<item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item>
- <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim_dark</item>
+ <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item>
<item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item>
- <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed_dark</item>
+ <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item>
<item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item>
- <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim_dark</item>
- <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed_dark</item>
- <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim_dark</item>
+ <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item>
+ <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item>
+ <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item>
<item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item>
<item name="materialColorErrorContainer">@color/system_error_container_dark</item>
- <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed_dark</item>
+ <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item>
<item name="materialColorPrimaryInverse">@color/system_primary_dark</item>
- <item name="materialColorSecondaryFixed">@color/system_secondary_fixed_dark</item>
+ <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
<item name="materialColorSurfaceInverse">@color/system_surface_dark</item>
<item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item>
<item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item>
- <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed_dark</item>
+ <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item>
<item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item>
<item name="materialColorOnBackground">@color/system_on_background_dark</item>
- <item name="materialColorPrimaryFixed">@color/system_primary_fixed_dark</item>
+ <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item>
<item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
<item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
<item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
@@ -5047,7 +5018,6 @@
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
- <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
</style>
<style name="Theme.DeviceDefault.AutofillHalfScreenDialogList" parent="Theme.DeviceDefault.DayNight">
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index ba05791..aea0178 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -259,20 +259,6 @@
}
@Test
- public void programSelectorToHalProgramSelector_withInvalidDabSelector_returnsNull() {
- ProgramSelector invalidDbSelector = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
- TEST_DAB_SID_EXT_ID,
- new ProgramSelector.Identifier[0],
- new long[0]);
-
- android.hardware.broadcastradio.ProgramSelector invalidHalDabSelector =
- ConversionUtils.programSelectorToHalProgramSelector(invalidDbSelector);
-
- expect.withMessage("Invalid HAL DAB selector without required secondary ids")
- .that(invalidHalDabSelector).isNull();
- }
-
- @Test
public void programSelectorFromHalProgramSelector_withValidSelector() {
android.hardware.broadcastradio.ProgramSelector halDabSelector =
AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
@@ -289,18 +275,6 @@
}
@Test
- public void programSelectorFromHalProgramSelector_withInvalidSelector_returnsNull() {
- android.hardware.broadcastradio.ProgramSelector invalidHalDabSelector =
- AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{});
-
- ProgramSelector invalidDabSelector =
- ConversionUtils.programSelectorFromHalProgramSelector(invalidHalDabSelector);
-
- expect.withMessage("Invalid DAB selector without required secondary ids")
- .that(invalidDabSelector).isNull();
- }
-
- @Test
public void programInfoFromHalProgramInfo_withValidProgramInfo() {
android.hardware.broadcastradio.ProgramSelector halDabSelector =
AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
index 7a1de0c..a753870 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
@@ -435,9 +435,11 @@
mActivityRule.runOnUiThread(s::start);
while (!listener.endIsCalled) {
- boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted() ||
- a4.isStarted() || a5.isStarted();
- assertEquals(passedStartDelay, s.isRunning());
+ mActivityRule.runOnUiThread(() -> {
+ boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted()
+ || a4.isStarted() || a5.isStarted();
+ assertEquals(passedStartDelay, s.isRunning());
+ });
Thread.sleep(50);
}
assertFalse(s.isRunning());
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
new file mode 100644
index 0000000..43266a5
--- /dev/null
+++ b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2023 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.animation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.util.PollingCheck;
+import android.view.View;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.MediumTest;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@MediumTest
+public class AnimatorSetCallsTest {
+ @Rule
+ public final ActivityScenarioRule<AnimatorSetActivity> mRule =
+ new ActivityScenarioRule<>(AnimatorSetActivity.class);
+
+ private AnimatorSetActivity mActivity;
+ private AnimatorSet mSet1;
+ private AnimatorSet mSet2;
+ private ObjectAnimator mAnimator;
+ private CountListener mListener1;
+ private CountListener mListener2;
+ private CountListener mListener3;
+
+ @Before
+ public void setUp() throws Exception {
+ mRule.getScenario().onActivity((activity) -> {
+ mActivity = activity;
+ View square = mActivity.findViewById(R.id.square1);
+
+ mSet1 = new AnimatorSet();
+ mListener1 = new CountListener();
+ mSet1.addListener(mListener1);
+ mSet1.addPauseListener(mListener1);
+
+ mSet2 = new AnimatorSet();
+ mListener2 = new CountListener();
+ mSet2.addListener(mListener2);
+ mSet2.addPauseListener(mListener2);
+
+ mAnimator = ObjectAnimator.ofFloat(square, "translationX", 0f, 100f);
+ mListener3 = new CountListener();
+ mAnimator.addListener(mListener3);
+ mAnimator.addPauseListener(mListener3);
+ mAnimator.setDuration(1);
+
+ mSet2.play(mAnimator);
+ mSet1.play(mSet2);
+ });
+ }
+
+ @Test
+ public void startEndCalledOnChildren() {
+ mRule.getScenario().onActivity((a) -> mSet1.start());
+ waitForOnUiThread(() -> mListener1.endForward > 0);
+
+ // only startForward and endForward should have been called once
+ mListener1.assertValues(
+ 1, 0, 1, 0, 0, 0, 0, 0
+ );
+ mListener2.assertValues(
+ 1, 0, 1, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 1, 0, 0, 0, 0, 0
+ );
+ }
+
+ @Test
+ public void cancelCalledOnChildren() {
+ mRule.getScenario().onActivity((a) -> {
+ mSet1.start();
+ mSet1.cancel();
+ });
+ waitForOnUiThread(() -> mListener1.endForward > 0);
+
+ // only startForward and endForward should have been called once
+ mListener1.assertValues(
+ 1, 0, 1, 0, 1, 0, 0, 0
+ );
+ mListener2.assertValues(
+ 1, 0, 1, 0, 1, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 1, 0, 1, 0, 0, 0
+ );
+ }
+
+ @Test
+ public void startEndReversedCalledOnChildren() {
+ mRule.getScenario().onActivity((a) -> mSet1.reverse());
+ waitForOnUiThread(() -> mListener1.endReverse > 0);
+
+ // only startForward and endForward should have been called once
+ mListener1.assertValues(
+ 0, 1, 0, 1, 0, 0, 0, 0
+ );
+ mListener2.assertValues(
+ 0, 1, 0, 1, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 0, 1, 0, 1, 0, 0, 0, 0
+ );
+ }
+
+ @Test
+ public void pauseResumeCalledOnChildren() {
+ mRule.getScenario().onActivity((a) -> {
+ mSet1.start();
+ mSet1.pause();
+ });
+ waitForOnUiThread(() -> mListener1.pause > 0);
+
+ // only startForward and pause should have been called once
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+
+ mRule.getScenario().onActivity((a) -> mSet1.resume());
+ waitForOnUiThread(() -> mListener1.endForward > 0);
+
+ // resume and endForward should have been called once
+ mListener1.assertValues(
+ 1, 0, 1, 0, 0, 0, 1, 1
+ );
+ mListener2.assertValues(
+ 1, 0, 1, 0, 0, 0, 1, 1
+ );
+ mListener3.assertValues(
+ 1, 0, 1, 0, 0, 0, 1, 1
+ );
+ }
+
+ @Test
+ public void updateOnlyWhileChangingValues() {
+ ArrayList<Float> updateValues = new ArrayList<>();
+ mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ updateValues.add((Float) animation.getAnimatedValue());
+ }
+ });
+
+ mSet1.setCurrentPlayTime(0);
+
+ assertEquals(1, updateValues.size());
+ assertEquals(0f, updateValues.get(0), 0f);
+ }
+
+ @Test
+ public void updateOnlyWhileRunning() {
+ ArrayList<Float> updateValues = new ArrayList<>();
+ mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ updateValues.add((Float) animation.getAnimatedValue());
+ }
+ });
+
+ mRule.getScenario().onActivity((a) -> {
+ mSet1.start();
+ });
+
+ waitForOnUiThread(() -> mListener1.endForward > 0);
+
+ // the duration is only 1ms, so there should only be two values, 0 and 100.
+ assertEquals(0f, updateValues.get(0), 0f);
+ assertEquals(100f, updateValues.get(updateValues.size() - 1), 0f);
+
+ // now check all the values in the middle, which can never go from 100->0.
+ boolean isAtEnd = false;
+ for (int i = 1; i < updateValues.size() - 1; i++) {
+ float actual = updateValues.get(i);
+ if (actual == 100f) {
+ isAtEnd = true;
+ }
+ float expected = isAtEnd ? 100f : 0f;
+ assertEquals(expected, actual, 0f);
+ }
+ }
+
+ @Test
+ public void pauseResumeSeekingAnimators() {
+ ValueAnimator animator2 = ValueAnimator.ofFloat(0f, 1f);
+ mSet2.play(animator2).after(mAnimator);
+ mSet2.setStartDelay(100);
+ mSet1.setStartDelay(100);
+ mAnimator.setDuration(100);
+
+ mActivity.runOnUiThread(() -> {
+ mSet1.setCurrentPlayTime(0);
+ mSet1.pause();
+
+ // only startForward and pause should have been called once
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener2.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener2.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.setCurrentPlayTime(200);
+
+ // resume and endForward should have been called once
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.pause();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 1
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 2
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+
+ // now go to animator2
+ mSet1.setCurrentPlayTime(400);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 3, 3
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 2
+ );
+ mListener3.assertValues(
+ 1, 0, 1, 0, 0, 0, 1, 1
+ );
+
+ // now go back to mAnimator
+ mSet1.setCurrentPlayTime(250);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 4, 4
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 3, 3
+ );
+ mListener3.assertValues(
+ 1, 1, 1, 0, 0, 0, 2, 2
+ );
+
+ // now go back to before mSet2 was being run
+ mSet1.setCurrentPlayTime(1);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 5, 5
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 1, 0, 0, 3, 3
+ );
+ mListener3.assertValues(
+ 1, 1, 1, 1, 0, 0, 2, 2
+ );
+ });
+ }
+
+ @Test
+ public void endInCancel() throws Throwable {
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mSet1.end();
+ }
+ };
+ mSet1.addListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.cancel();
+ // Should go to the end value
+ View square = mActivity.findViewById(R.id.square1);
+ assertEquals(100f, square.getTranslationX(), 0.001f);
+ });
+ }
+
+ @Test
+ public void reentrantStart() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation, boolean isReverse) {
+ mSet1.start();
+ latch.countDown();
+ }
+ };
+ mSet1.addListener(listener);
+ mSet2.addListener(listener);
+ mAnimator.addListener(listener);
+ mActivity.runOnUiThread(() -> mSet1.start());
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantEnd() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ mSet1.end();
+ latch.countDown();
+ }
+ };
+ mSet1.addListener(listener);
+ mSet2.addListener(listener);
+ mAnimator.addListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.end();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantPause() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationPause(Animator animation) {
+ mSet1.pause();
+ latch.countDown();
+ }
+ };
+ mSet1.addPauseListener(listener);
+ mSet2.addPauseListener(listener);
+ mAnimator.addPauseListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.pause();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantResume() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationResume(Animator animation) {
+ mSet1.resume();
+ latch.countDown();
+ }
+ };
+ mSet1.addPauseListener(listener);
+ mSet2.addPauseListener(listener);
+ mAnimator.addPauseListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.pause();
+ mSet1.resume();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ private void waitForOnUiThread(PollingCheck.PollingCheckCondition condition) {
+ final boolean[] value = new boolean[1];
+ PollingCheck.waitFor(() -> {
+ mActivity.runOnUiThread(() -> value[0] = condition.canProceed());
+ return value[0];
+ });
+ }
+
+ private static class CountListener implements Animator.AnimatorListener,
+ Animator.AnimatorPauseListener {
+ public int startNoParam;
+ public int endNoParam;
+ public int startReverse;
+ public int startForward;
+ public int endForward;
+ public int endReverse;
+ public int cancel;
+ public int repeat;
+ public int pause;
+ public int resume;
+
+ public void assertValues(
+ int startForward,
+ int startReverse,
+ int endForward,
+ int endReverse,
+ int cancel,
+ int repeat,
+ int pause,
+ int resume
+ ) {
+ assertEquals("onAnimationStart() without direction", 0, startNoParam);
+ assertEquals("onAnimationEnd() without direction", 0, endNoParam);
+ assertEquals("onAnimationStart(forward)", startForward, this.startForward);
+ assertEquals("onAnimationStart(reverse)", startReverse, this.startReverse);
+ assertEquals("onAnimationEnd(forward)", endForward, this.endForward);
+ assertEquals("onAnimationEnd(reverse)", endReverse, this.endReverse);
+ assertEquals("onAnimationCancel()", cancel, this.cancel);
+ assertEquals("onAnimationRepeat()", repeat, this.repeat);
+ assertEquals("onAnimationPause()", pause, this.pause);
+ assertEquals("onAnimationResume()", resume, this.resume);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation, boolean isReverse) {
+ if (isReverse) {
+ startReverse++;
+ } else {
+ startForward++;
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ if (isReverse) {
+ endReverse++;
+ } else {
+ endForward++;
+ }
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ startNoParam++;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ endNoParam++;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ cancel++;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ repeat++;
+ }
+
+ @Override
+ public void onAnimationPause(Animator animation) {
+ pause++;
+ }
+
+ @Override
+ public void onAnimationResume(Animator animation) {
+ resume++;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
index dee0a3e..a53d57f 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -40,6 +40,8 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
@MediumTest
@@ -1067,6 +1069,64 @@
});
}
+ @Test
+ public void reentrantStart() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation, boolean isReverse) {
+ a1.start();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> a1.start());
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantPause() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addPauseListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationPause(Animator animation) {
+ a1.pause();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> {
+ a1.start();
+ a1.pause();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantResume() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addPauseListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationResume(Animator animation) {
+ a1.resume();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> {
+ a1.start();
+ a1.pause();
+ a1.resume();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
boolean wasRunning = false;
long firstRunningFrameTime = -1;
diff --git a/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java b/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
index 81cd4da..8cc88ea 100644
--- a/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
+++ b/core/tests/coretests/src/android/animation/ViewPropertyAnimatorTest.java
@@ -135,11 +135,15 @@
* @throws Exception
*/
@Before
- public void setUp() throws Exception {
+ public void setUp() throws Throwable {
final BasicAnimatorActivity activity = mActivityRule.getActivity();
Button button = activity.findViewById(R.id.animatingButton);
mAnimator = button.animate().x(100).y(100);
+ mActivityRule.runOnUiThread(() -> {
+ mAnimator.start();
+ mAnimator.cancel();
+ });
// mListener is the main testing mechanism of this file. The asserts of each test
// are embedded in the listener callbacks that it implements.
diff --git a/core/tests/coretests/src/android/credentials/CredentialManagerTest.java b/core/tests/coretests/src/android/credentials/CredentialManagerTest.java
index e31d5ae..6f0c3d3 100644
--- a/core/tests/coretests/src/android/credentials/CredentialManagerTest.java
+++ b/core/tests/coretests/src/android/credentials/CredentialManagerTest.java
@@ -141,8 +141,9 @@
@Test
public void testGetCredential_nullRequest() {
+ GetCredentialRequest nullRequest = null;
assertThrows(NullPointerException.class,
- () -> mCredentialManager.getCredential(null, mMockActivity, null, mExecutor,
+ () -> mCredentialManager.getCredential(nullRequest, mMockActivity, null, mExecutor,
result -> {
}));
}
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java
new file mode 100644
index 0000000..4e59064
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 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.hardware.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.SurfaceTexture;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.util.DisplayMetrics;
+import android.view.ContentRecordingSession;
+import android.view.Surface;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+
+/**
+ * Tests for non-public APIs in {@link VirtualDisplayConfig}.
+ * See also related CTS tests.
+ *
+ * Run with:
+ * atest FrameworksCoreTests:VirtualDisplayConfigTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VirtualDisplayConfigTest {
+
+ private static final String NAME = "VirtualDisplayConfigTest";
+ private static final int WIDTH = 720;
+ private static final int HEIGHT = 480;
+ private static final int DENSITY = DisplayMetrics.DENSITY_MEDIUM;
+ private static final float REQUESTED_REFRESH_RATE = 30.0f;
+ private static final int FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
+ | DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
+
+ // Values for hidden APIs.
+ private static final int DISPLAY_ID_TO_MIRROR = 10;
+ private static final IBinder WINDOW_TOKEN = new Binder("DisplayContentWindowToken");
+ private static final ContentRecordingSession CONTENT_RECORDING_SESSION =
+ ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+
+ private final Surface mSurface = new Surface(new SurfaceTexture(/*texName=*/1));
+
+ @Test
+ public void testParcelAndUnparcel_matches() {
+ final VirtualDisplayConfig originalConfig = buildGenericVirtualDisplay(NAME);
+
+ validateConstantFields(originalConfig);
+ assertThat(originalConfig.getName()).isEqualTo(NAME);
+
+
+ final Parcel parcel = Parcel.obtain();
+ originalConfig.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+ final VirtualDisplayConfig recreatedConfig =
+ VirtualDisplayConfig.CREATOR.createFromParcel(parcel);
+
+ validateConstantFields(recreatedConfig);
+ assertThat(recreatedConfig.getName()).isEqualTo(NAME);
+ }
+
+ @Test
+ public void testEquals_matches() {
+ assertThat(buildGenericVirtualDisplay(NAME)).isEqualTo(buildGenericVirtualDisplay(NAME));
+ }
+
+ @Test
+ public void testEquals_different() {
+ assertThat(buildGenericVirtualDisplay(NAME + "2")).isNotEqualTo(
+ buildGenericVirtualDisplay(NAME));
+ }
+
+ private VirtualDisplayConfig buildGenericVirtualDisplay(String name) {
+ return new VirtualDisplayConfig.Builder(name, WIDTH, HEIGHT, DENSITY)
+ .setFlags(FLAGS)
+ .setSurface(mSurface)
+ .setDisplayCategories(Set.of("C1", "C2"))
+ .addDisplayCategory("C3")
+ .setRequestedRefreshRate(REQUESTED_REFRESH_RATE)
+ .setDisplayIdToMirror(DISPLAY_ID_TO_MIRROR)
+ .setWindowManagerMirroringEnabled(true)
+ .setContentRecordingSession(CONTENT_RECORDING_SESSION)
+ .build();
+ }
+
+ private void validateConstantFields(VirtualDisplayConfig config) {
+ assertThat(config.getWidth()).isEqualTo(WIDTH);
+ assertThat(config.getHeight()).isEqualTo(HEIGHT);
+ assertThat(config.getDensityDpi()).isEqualTo(DENSITY);
+ assertThat(config.getFlags()).isEqualTo(FLAGS);
+ assertThat(config.getSurface()).isNotNull();
+ assertThat(config.getDisplayCategories()).containsExactly("C1", "C2", "C3");
+ assertThat(config.getRequestedRefreshRate()).isEqualTo(REQUESTED_REFRESH_RATE);
+ assertThat(config.getDisplayIdToMirror()).isEqualTo(DISPLAY_ID_TO_MIRROR);
+ assertThat(config.isWindowManagerMirroringEnabled()).isTrue();
+ assertThat(config.getContentRecordingSession()).isEqualTo(CONTENT_RECORDING_SESSION);
+ }
+}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 91fbe00..394ff0a 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -54,6 +54,7 @@
import android.content.Context;
import android.os.FileUtils.MemoryPipe;
import android.provider.DocumentsContract.Document;
+import android.util.DataUnit;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -504,31 +505,45 @@
@Test
public void testRoundStorageSize() throws Exception {
- final long M128 = 128000000L;
- final long M256 = 256000000L;
- final long M512 = 512000000L;
- final long G1 = 1000000000L;
- final long G2 = 2000000000L;
- final long G16 = 16000000000L;
- final long G32 = 32000000000L;
- final long G64 = 64000000000L;
+ final long GB1 = DataUnit.GIGABYTES.toBytes(1);
+ final long GiB1 = DataUnit.GIBIBYTES.toBytes(1);
+ final long GB2 = DataUnit.GIGABYTES.toBytes(2);
+ final long GiB2 = DataUnit.GIBIBYTES.toBytes(2);
+ final long GiB128 = DataUnit.GIBIBYTES.toBytes(128);
+ final long GB256 = DataUnit.GIGABYTES.toBytes(256);
+ final long GiB256 = DataUnit.GIBIBYTES.toBytes(256);
+ final long GB512 = DataUnit.GIGABYTES.toBytes(512);
+ final long GiB512 = DataUnit.GIBIBYTES.toBytes(512);
+ final long TB1 = DataUnit.TERABYTES.toBytes(1);
+ final long TiB1 = DataUnit.TEBIBYTES.toBytes(1);
+ final long TB2 = DataUnit.TERABYTES.toBytes(2);
+ final long TiB2 = DataUnit.TEBIBYTES.toBytes(2);
+ final long TB4 = DataUnit.TERABYTES.toBytes(4);
+ final long TiB4 = DataUnit.TEBIBYTES.toBytes(4);
+ final long TB8 = DataUnit.TERABYTES.toBytes(8);
+ final long TiB8 = DataUnit.TEBIBYTES.toBytes(8);
- assertEquals(M128, roundStorageSize(M128));
- assertEquals(M256, roundStorageSize(M128 + 1));
- assertEquals(M256, roundStorageSize(M256 - 1));
- assertEquals(M256, roundStorageSize(M256));
- assertEquals(M512, roundStorageSize(M256 + 1));
- assertEquals(M512, roundStorageSize(M512 - 1));
- assertEquals(M512, roundStorageSize(M512));
- assertEquals(G1, roundStorageSize(M512 + 1));
- assertEquals(G1, roundStorageSize(G1));
- assertEquals(G2, roundStorageSize(G1 + 1));
+ assertEquals(GB1, roundStorageSize(GB1 - 1));
+ assertEquals(GB1, roundStorageSize(GB1));
+ assertEquals(GB1, roundStorageSize(GB1 + 1));
+ assertEquals(GB1, roundStorageSize(GiB1 - 1));
+ assertEquals(GB1, roundStorageSize(GiB1));
+ assertEquals(GB2, roundStorageSize(GiB1 + 1));
+ assertEquals(GB2, roundStorageSize(GiB2));
- assertEquals(G16, roundStorageSize(G16));
- assertEquals(G32, roundStorageSize(G16 + 1));
- assertEquals(G32, roundStorageSize(G32 - 1));
- assertEquals(G32, roundStorageSize(G32));
- assertEquals(G64, roundStorageSize(G32 + 1));
+ assertEquals(GB256, roundStorageSize(GiB128 + 1));
+ assertEquals(GB256, roundStorageSize(GiB256));
+ assertEquals(GB512, roundStorageSize(GiB256 + 1));
+ assertEquals(GB512, roundStorageSize(GiB512));
+ assertEquals(TB1, roundStorageSize(GiB512 + 1));
+ assertEquals(TB1, roundStorageSize(TiB1));
+ assertEquals(TB2, roundStorageSize(TiB1 + 1));
+ assertEquals(TB2, roundStorageSize(TiB2));
+ assertEquals(TB4, roundStorageSize(TiB2 + 1));
+ assertEquals(TB4, roundStorageSize(TiB4));
+ assertEquals(TB8, roundStorageSize(TiB4 + 1));
+ assertEquals(TB8, roundStorageSize(TiB8));
+ assertEquals(TB1, roundStorageSize(1013077688320L)); // b/268571529
}
@Test
diff --git a/core/tests/coretests/src/android/util/DataUnitTest.java b/core/tests/coretests/src/android/util/DataUnitTest.java
index ec296b7..034cbdd 100644
--- a/core/tests/coretests/src/android/util/DataUnitTest.java
+++ b/core/tests/coretests/src/android/util/DataUnitTest.java
@@ -26,11 +26,13 @@
assertEquals(12_000L, DataUnit.KILOBYTES.toBytes(12));
assertEquals(12_000_000L, DataUnit.MEGABYTES.toBytes(12));
assertEquals(12_000_000_000L, DataUnit.GIGABYTES.toBytes(12));
+ assertEquals(12_000_000_000_000L, DataUnit.TERABYTES.toBytes(12));
}
public void testIec() throws Exception {
assertEquals(12_288L, DataUnit.KIBIBYTES.toBytes(12));
assertEquals(12_582_912L, DataUnit.MEBIBYTES.toBytes(12));
assertEquals(12_884_901_888L, DataUnit.GIBIBYTES.toBytes(12));
+ assertEquals(13_194_139_533_312L, DataUnit.TEBIBYTES.toBytes(12));
}
}
diff --git a/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
index df96a7d..b3fe5c8 100644
--- a/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
+++ b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
@@ -89,20 +89,22 @@
}
@Test
- public void testIsSameDisplay() {
- assertThat(ContentRecordingSession.isSameDisplay(null, null)).isFalse();
+ public void testIsProjectionOnSameDisplay() {
+ assertThat(ContentRecordingSession.isProjectionOnSameDisplay(null, null)).isFalse();
ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
WINDOW_TOKEN);
session.setDisplayId(DEFAULT_DISPLAY);
- assertThat(ContentRecordingSession.isSameDisplay(session, null)).isFalse();
+ assertThat(ContentRecordingSession.isProjectionOnSameDisplay(session, null)).isFalse();
ContentRecordingSession incomingSession = ContentRecordingSession.createDisplaySession(
WINDOW_TOKEN);
incomingSession.setDisplayId(DEFAULT_DISPLAY);
- assertThat(ContentRecordingSession.isSameDisplay(session, incomingSession)).isTrue();
+ assertThat(ContentRecordingSession.isProjectionOnSameDisplay(session,
+ incomingSession)).isTrue();
incomingSession.setDisplayId(DEFAULT_DISPLAY + 1);
- assertThat(ContentRecordingSession.isSameDisplay(session, incomingSession)).isFalse();
+ assertThat(ContentRecordingSession.isProjectionOnSameDisplay(session,
+ incomingSession)).isFalse();
}
@Test
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index 3d4918b..6d635af 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -58,7 +58,7 @@
// The number of flags held in boolean properties. Their values should also be double-checked
// in the methods above.
- private static final int NUM_BOOLEAN_PROPERTIES = 27;
+ private static final int NUM_BOOLEAN_PROPERTIES = 26;
@Test
public void testStandardActions_serializationFlagIsValid() {
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index fccb177..8ae6381 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -269,6 +269,41 @@
}
@Test
+ public void onTouchEvent_startHandwriting_delegate_touchEventsHandled() {
+ // There is no delegator view and the delegate callback does nothing so handwriting will not
+ // be started. This is so we can test how touch events are handled before handwriting is
+ // started.
+ mTestView1.setHandwritingDelegatorCallback(() -> {});
+
+ final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
+ final int y = (sHwArea1.top + sHwArea1.bottom) / 2;
+ MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y, 0);
+ boolean onTouchEventResult1 = mHandwritingInitiator.onTouchEvent(stylusEvent1);
+
+ final int x2 = x1 + mHandwritingSlop / 2;
+ MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y, 0);
+ boolean onTouchEventResult2 = mHandwritingInitiator.onTouchEvent(stylusEvent2);
+
+ final int x3 = x2 + mHandwritingSlop * 2;
+ MotionEvent stylusEvent3 = createStylusEvent(ACTION_MOVE, x3, y, 0);
+ boolean onTouchEventResult3 = mHandwritingInitiator.onTouchEvent(stylusEvent3);
+
+ final int x4 = x3 + mHandwritingSlop * 2;
+ MotionEvent stylusEvent4 = createStylusEvent(ACTION_MOVE, x4, y, 0);
+ boolean onTouchEventResult4 = mHandwritingInitiator.onTouchEvent(stylusEvent4);
+
+ assertThat(onTouchEventResult1).isFalse();
+ // stylusEvent2 does not trigger delegation since the touch slop distance has not been
+ // exceeded. onTouchEvent should return false so that the event is dispatched to the view
+ // tree.
+ assertThat(onTouchEventResult2).isFalse();
+ // After delegation is triggered by stylusEvent3, onTouchEvent should return true for
+ // ACTION_MOVE events so that the events are not dispatched to the view tree.
+ assertThat(onTouchEventResult3).isTrue();
+ assertThat(onTouchEventResult4).isTrue();
+ }
+
+ @Test
public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() {
final Rect rect = new Rect(600, 600, 900, 900);
final View testView = createView(rect, true /* autoHandwritingEnabled */,
diff --git a/core/tests/expresslog/src/com/android/internal/expresslog/ScaledRangeOptionsTest.java b/core/tests/expresslog/src/com/android/internal/expresslog/ScaledRangeOptionsTest.java
new file mode 100644
index 0000000..ee62d75
--- /dev/null
+++ b/core/tests/expresslog/src/com/android/internal/expresslog/ScaledRangeOptionsTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.expresslog;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+@SmallTest
+public class ScaledRangeOptionsTest {
+ private static final String TAG = ScaledRangeOptionsTest.class.getSimpleName();
+
+ @Test
+ public void testGetBinsCount() {
+ Histogram.ScaledRangeOptions options1 = new Histogram.ScaledRangeOptions(1, 100, 100, 2);
+ assertEquals(3, options1.getBinsCount());
+
+ Histogram.ScaledRangeOptions options10 = new Histogram.ScaledRangeOptions(10, 100, 100, 2);
+ assertEquals(12, options10.getBinsCount());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructZeroBinsCount() {
+ new Histogram.ScaledRangeOptions(0, 100, 100, 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructNegativeBinsCount() {
+ new Histogram.ScaledRangeOptions(-1, 100, 100, 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructNegativeFirstBinWidth() {
+ new Histogram.ScaledRangeOptions(10, 100, -100, 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructTooSmallFirstBinWidth() {
+ new Histogram.ScaledRangeOptions(10, 100, 0.5f, 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructNegativeScaleFactor() {
+ new Histogram.ScaledRangeOptions(10, 100, 100, -2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructTooSmallScaleFactor() {
+ new Histogram.ScaledRangeOptions(10, 100, 100, 0.5f);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructTooBigScaleFactor() {
+ new Histogram.ScaledRangeOptions(10, 100, 100, 500.f);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructTooBigBinRange() {
+ new Histogram.ScaledRangeOptions(100, 100, 100, 10.f);
+ }
+
+ @Test
+ public void testBinIndexForRangeEqual1() {
+ Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 1, 1);
+ assertEquals(12, options.getBinsCount());
+
+ assertEquals(11, options.getBinForSample(11));
+
+ for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
+ assertEquals(i, options.getBinForSample(i));
+ }
+ }
+
+ @Test
+ public void testBinIndexForRangeEqual2() {
+ // this should produce bin otpions similar to linear histogram with bin width 2
+ Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 2, 1);
+ assertEquals(12, options.getBinsCount());
+
+ for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
+ assertEquals(i, options.getBinForSample(i * 2));
+ assertEquals(i, options.getBinForSample(i * 2 - 1));
+ }
+ }
+
+ @Test
+ public void testBinIndexForRangeEqual5() {
+ Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(2, 0, 5, 1);
+ assertEquals(4, options.getBinsCount());
+ for (int i = 0; i < 2; i++) {
+ for (int sample = 0; sample < 5; sample++) {
+ assertEquals(i + 1, options.getBinForSample(i * 5 + sample));
+ }
+ }
+ }
+
+ @Test
+ public void testBinIndexForRangeEqual10() {
+ Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 10, 1);
+ assertEquals(0, options.getBinForSample(0));
+ assertEquals(options.getBinsCount() - 2, options.getBinForSample(100));
+ assertEquals(options.getBinsCount() - 1, options.getBinForSample(101));
+
+ final float binSize = (101 - 1) / 10f;
+ for (int i = 1, bins = options.getBinsCount() - 1; i < bins; i++) {
+ assertEquals(i, options.getBinForSample(i * binSize));
+ }
+ }
+
+ @Test
+ public void testBinIndexForScaleFactor2() {
+ final int binsCount = 10;
+ final int minValue = 10;
+ final int firstBinWidth = 5;
+ final int scaledFactor = 2;
+
+ Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(
+ binsCount, minValue, firstBinWidth, scaledFactor);
+ assertEquals(binsCount + 2, options.getBinsCount());
+ long[] binCounts = new long[10];
+
+ // precalculate max valid value - start value for the overflow bin
+ int lastBinStartValue = minValue; //firstBinMin value
+ int lastBinWidth = firstBinWidth;
+ for (int binIdx = 2; binIdx <= binsCount + 1; binIdx++) {
+ lastBinStartValue = lastBinStartValue + lastBinWidth;
+ lastBinWidth *= scaledFactor;
+ }
+
+ // underflow bin
+ for (int i = 1; i < minValue; i++) {
+ assertEquals(0, options.getBinForSample(i));
+ }
+
+ for (int i = 10; i < lastBinStartValue; i++) {
+ assertTrue(options.getBinForSample(i) > 0);
+ assertTrue(options.getBinForSample(i) <= binsCount);
+ binCounts[options.getBinForSample(i) - 1]++;
+ }
+
+ // overflow bin
+ assertEquals(binsCount + 1, options.getBinForSample(lastBinStartValue));
+
+ for (int i = 1; i < binsCount; i++) {
+ assertEquals(binCounts[i], binCounts[i - 1] * 2L);
+ }
+ }
+}
diff --git a/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java b/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java
index 9fa6d06..037dbb3 100644
--- a/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java
+++ b/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java
@@ -24,11 +24,11 @@
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
+@SmallTest
public class UniformOptionsTest {
private static final String TAG = UniformOptionsTest.class.getSimpleName();
@Test
- @SmallTest
public void testGetBinsCount() {
Histogram.UniformOptions options1 = new Histogram.UniformOptions(1, 100, 1000);
assertEquals(3, options1.getBinsCount());
@@ -38,25 +38,21 @@
}
@Test(expected = IllegalArgumentException.class)
- @SmallTest
public void testConstructZeroBinsCount() {
new Histogram.UniformOptions(0, 100, 1000);
}
@Test(expected = IllegalArgumentException.class)
- @SmallTest
public void testConstructNegativeBinsCount() {
new Histogram.UniformOptions(-1, 100, 1000);
}
@Test(expected = IllegalArgumentException.class)
- @SmallTest
public void testConstructMaxValueLessThanMinValue() {
new Histogram.UniformOptions(10, 1000, 100);
}
@Test
- @SmallTest
public void testBinIndexForRangeEqual1() {
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 11);
for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
@@ -65,7 +61,6 @@
}
@Test
- @SmallTest
public void testBinIndexForRangeEqual2() {
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 21);
for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
@@ -75,7 +70,6 @@
}
@Test
- @SmallTest
public void testBinIndexForRangeEqual5() {
Histogram.UniformOptions options = new Histogram.UniformOptions(2, 0, 10);
assertEquals(4, options.getBinsCount());
@@ -87,7 +81,6 @@
}
@Test
- @SmallTest
public void testBinIndexForRangeEqual10() {
Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 101);
assertEquals(0, options.getBinForSample(0));
@@ -101,7 +94,6 @@
}
@Test
- @SmallTest
public void testBinIndexForRangeEqual90() {
final int binCount = 10;
final int minValue = 100;
diff --git a/data/etc/TEST_MAPPING b/data/etc/TEST_MAPPING
index 1a5db2f..5927720 100644
--- a/data/etc/TEST_MAPPING
+++ b/data/etc/TEST_MAPPING
@@ -2,10 +2,10 @@
"presubmit": [
{
"file_patterns": ["(/|^)platform.xml"],
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
}
diff --git a/data/etc/com.android.intentresolver.xml b/data/etc/com.android.intentresolver.xml
index f4e94ad..af64926 100644
--- a/data/etc/com.android.intentresolver.xml
+++ b/data/etc/com.android.intentresolver.xml
@@ -19,5 +19,6 @@
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
+ <permission name="android.permission.QUERY_CLONED_APPS"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 6328b02..2c85fe4 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -160,6 +160,7 @@
<assign-permission name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" uid="media" />
<assign-permission name="android.permission.REGISTER_STATS_PULL_ATOM" uid="media" />
<assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="media" />
+ <assign-permission name="android.permission.LOG_FOREGROUND_RESOURCE_USE" uid="media" />
<assign-permission name="android.permission.INTERNET" uid="media" />
@@ -173,6 +174,7 @@
<assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="audioserver" />
<assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="audioserver" />
<assign-permission name="android.permission.OBSERVE_SENSOR_PRIVACY" uid="audioserver" />
+ <assign-permission name="android.permission.LOG_FOREGROUND_RESOURCE_USE" uid="audioserver" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="cameraserver" />
<assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="cameraserver" />
@@ -186,6 +188,7 @@
<assign-permission name="android.permission.MANAGE_APP_OPS_MODES" uid="cameraserver" />
<assign-permission name="android.permission.OBSERVE_SENSOR_PRIVACY" uid="cameraserver" />
<assign-permission name="android.permission.REAL_GET_TASKS" uid="cameraserver" />
+ <assign-permission name="android.permission.LOG_FOREGROUND_RESOURCE_USE" uid="cameraserver" />
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 5549f88..a73010b 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -7,24 +7,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-2123789565": {
- "message": "Found no matching mirror display for id=%d for DEFAULT_DISPLAY. Nothing to mirror.",
- "level": "WARN",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-2121056984": {
"message": "%s",
"level": "WARN",
"group": "WM_DEBUG_LOCKTASK",
"at": "com\/android\/server\/wm\/LockTaskController.java"
},
- "-2113780196": {
- "message": "Successfully created a ContentRecordingSession for displayId=%d to mirror content from displayId=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-2111539867": {
"message": "remove IME snapshot, caller=%s",
"level": "INFO",
@@ -67,12 +55,24 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-2074882083": {
+ "message": "Content Recording: Unable to retrieve task to start recording for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-2072089308": {
"message": "Attempted to add window with token that is a sub-window: %s. Aborting.",
"level": "WARN",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-2072029833": {
+ "message": "Content Recording: Found no matching mirror display for id=%d for DEFAULT_DISPLAY. Nothing to mirror.",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-2054442123": {
"message": "Setting Intent of %s to %s",
"level": "VERBOSE",
@@ -175,12 +175,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1944652783": {
- "message": "Unable to tell MediaProjectionManagerService to stop the active projection: %s",
- "level": "ERROR",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1941440781": {
"message": "Creating Pending Move-to-back: %s",
"level": "VERBOSE",
@@ -253,12 +247,24 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "-1885450608": {
+ "message": "Content Recording: Successfully created a ContentRecordingSession for displayId=%d to mirror content from displayId=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-1884933373": {
"message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
"level": "INFO",
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1883484959": {
+ "message": "Content Recording: Display %d state is now (%d), so update recording?",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-1872288685": {
"message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s",
"level": "VERBOSE",
@@ -355,12 +361,6 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-1781861035": {
- "message": "Display %d has content (%b) so pause recording",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1777196134": {
"message": "goodToGo(): No apps to animate, mPendingAnimations=%d",
"level": "DEBUG",
@@ -505,12 +505,6 @@
"group": "WM_DEBUG_LOCKTASK",
"at": "com\/android\/server\/wm\/LockTaskController.java"
},
- "-1605829532": {
- "message": "Unable to start recording due to null token for display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1598452494": {
"message": "activityDestroyedLocked: r=%s",
"level": "DEBUG",
@@ -571,6 +565,12 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
},
+ "-1549923951": {
+ "message": "Content Recording: Unable to retrieve window container to start recording for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1545962566": {
"message": "View server did not start",
"level": "WARN",
@@ -649,6 +649,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-1480264178": {
+ "message": "Content Recording: Unable to update recording for display %d to new bounds %s and\/or orientation %d, since the surface is not available.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1478175541": {
"message": "No longer animating wallpaper targets!",
"level": "VERBOSE",
@@ -721,12 +727,6 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1423223548": {
- "message": "Unable to tell MediaProjectionManagerService about resizing the active projection: %s",
- "level": "ERROR",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1421296808": {
"message": "Moving to RESUMED: %s (in existing)",
"level": "VERBOSE",
@@ -787,12 +787,6 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/RootWindowContainer.java"
},
- "-1373875178": {
- "message": "Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d.",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1364754753": {
"message": "Task vanished taskId=%d",
"level": "VERBOSE",
@@ -817,12 +811,6 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-1326876381": {
- "message": "Provided surface for recording on display %d is not present, so do not update the surface",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1323783276": {
"message": "performEnableScreen: bootFinished() failed.",
"level": "WARN",
@@ -943,6 +931,12 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimationController.java"
},
+ "-1217596375": {
+ "message": "Content Recording: Display %d has no content and is on, so start recording for state %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1209252064": {
"message": "Clear animatingExit: reason=clearAnimatingFlags win=%s",
"level": "DEBUG",
@@ -991,6 +985,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/Task.java"
},
+ "-1156314529": {
+ "message": "Content Recording: Unexpectedly null window container; unable to update recording for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1156118957": {
"message": "Updated config=%s",
"level": "DEBUG",
@@ -1015,6 +1015,12 @@
"group": "WM_DEBUG_FOCUS",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-1136734598": {
+ "message": "Content Recording: Ignoring session on same display %d, with an existing session %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+ },
"-1136467585": {
"message": "The listener does not exist.",
"level": "INFO",
@@ -1087,6 +1093,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "-1097851684": {
+ "message": "Content Recording: Unable to start recording due to null token for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1089874824": {
"message": "SURFACE SHOW (performLayout): %s",
"level": "INFO",
@@ -1147,12 +1159,6 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/RootWindowContainer.java"
},
- "-1018968224": {
- "message": "Recorded task is removed, so stop recording on display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-1016578046": {
"message": "Moving to %s Relaunching %s callers=%s",
"level": "INFO",
@@ -1297,6 +1303,12 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-869242375": {
+ "message": "Content Recording: Unable to start recording due to invalid region for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-863438038": {
"message": "Aborting Transition: %d",
"level": "VERBOSE",
@@ -1351,12 +1363,6 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-838378223": {
- "message": "Attempting to mirror self on %d",
- "level": "WARN",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-814760297": {
"message": "Looking for task of %s in %s",
"level": "DEBUG",
@@ -1429,6 +1435,12 @@
"group": "WM_DEBUG_FOCUS_LIGHT",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-767091913": {
+ "message": "Content Recording: Handle incoming session on display %d, with a pre-existing session %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+ },
"-766059044": {
"message": "Display id=%d selected orientation %s (%d), got rotation %s (%d)",
"level": "VERBOSE",
@@ -1453,12 +1465,6 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-751255162": {
- "message": "Unable to update recording for display %d to new bounds %s and\/or orientation %d, since the surface is not available.",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-743856570": {
"message": "shouldWaitAnimatingExit: isAnimating: %s",
"level": "DEBUG",
@@ -1471,18 +1477,6 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-732715767": {
- "message": "Unable to retrieve window container to start recording for display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
- "-729864558": {
- "message": "Attempting to mirror %d from %d but no DisplayContent associated. Changing to mirror default display.",
- "level": "WARN",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-729530161": {
"message": "Moving to DESTROYED: %s (no app)",
"level": "VERBOSE",
@@ -1717,6 +1711,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
+ "-517666355": {
+ "message": "Content Recording: Display %d has content (%b) so pause recording",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-509601642": {
"message": " checking %s",
"level": "VERBOSE",
@@ -1771,6 +1771,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/Task.java"
},
+ "-452750194": {
+ "message": "Content Recording: Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-451552570": {
"message": "Current focused window being animated by recents. Overriding back callback to recents controller callback.",
"level": "DEBUG",
@@ -1855,12 +1861,6 @@
"group": "WM_DEBUG_KEEP_SCREEN_ON",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
- "-381522987": {
- "message": "Display %d state is now (%d), so update recording?",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-381475323": {
"message": "DisplayContent: boot is waiting for window of type %d to be drawn",
"level": "DEBUG",
@@ -1969,12 +1969,6 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
- "-302468137": {
- "message": "Display %d was already recording, so apply transformations if necessary",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-292790591": {
"message": "Attempted to set IME policy to a display that does not exist: %d",
"level": "WARN",
@@ -1993,12 +1987,6 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-254406860": {
- "message": "Unable to tell MediaProjectionManagerService about visibility change on the active projection: %s",
- "level": "ERROR",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-251259736": {
"message": "No longer freezing: %s",
"level": "VERBOSE",
@@ -2017,12 +2005,6 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/AppTransitionController.java"
},
- "-237664290": {
- "message": "Pause the recording session on display %s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecordingController.java"
- },
"-235225312": {
"message": "Skipping config check for initializing activity: %s",
"level": "VERBOSE",
@@ -2077,6 +2059,12 @@
"group": "WM_DEBUG_WALLPAPER",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-180594244": {
+ "message": "Content Recording: Unable to tell MediaProjectionManagerService about visibility change on the active projection: %s",
+ "level": "ERROR",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-177040661": {
"message": "Start rotation animation. customAnim=%s, mCurRotation=%s, mOriginalRotation=%s",
"level": "DEBUG",
@@ -2113,12 +2101,6 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/Task.java"
},
- "-142844021": {
- "message": "Unable to start recording for display %d since the surface is not available.",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"-134091882": {
"message": "Screenshotting Activity %s",
"level": "VERBOSE",
@@ -2161,6 +2143,12 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-88873335": {
+ "message": "Content Recording: Unable to tell MediaProjectionManagerService to stop the active projection: %s",
+ "level": "ERROR",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-87705714": {
"message": "findFocusedWindow: focusedApp=null using new focus @ %s",
"level": "VERBOSE",
@@ -2347,12 +2335,6 @@
"group": "WM_DEBUG_FOCUS",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "96494268": {
- "message": "Stop MediaProjection on virtual display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"100936473": {
"message": "Wallpaper animation!",
"level": "VERBOSE",
@@ -2551,12 +2533,6 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/TransitionController.java"
},
- "264036181": {
- "message": "Unable to retrieve task to start recording for display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"269576220": {
"message": "Resuming rotation after drag",
"level": "DEBUG",
@@ -2665,6 +2641,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "339482207": {
+ "message": "Content Recording: Display %d was already recording, so apply transformations if necessary",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"341055768": {
"message": "resumeTopActivity: Skip resume: need to start pausing",
"level": "VERBOSE",
@@ -2959,8 +2941,8 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/Session.java"
},
- "609880497": {
- "message": "Display %d has no content and is on, so start recording for state %d",
+ "612856628": {
+ "message": "Content Recording: Stop MediaProjection on virtual display %d",
"level": "VERBOSE",
"group": "WM_DEBUG_CONTENT_RECORDING",
"at": "com\/android\/server\/wm\/ContentRecorder.java"
@@ -3139,12 +3121,6 @@
"group": "WM_DEBUG_ANIM",
"at": "com\/android\/server\/wm\/WindowContainer.java"
},
- "778774915": {
- "message": "Unable to record task since feature is disabled %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"781471998": {
"message": "moveWindowTokenToDisplay: Cannot move to the original display for token: %s",
"level": "WARN",
@@ -3181,6 +3157,12 @@
"group": "WM_DEBUG_SYNC_ENGINE",
"at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
},
+ "801521566": {
+ "message": "Content Recording: Attempting to mirror %d from %d but no DisplayContent associated. Changing to mirror default display.",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"806891543": {
"message": "Setting mOrientationChangeComplete=true because wtoken %s numInteresting=%d numDrawn=%d",
"level": "INFO",
@@ -3271,6 +3253,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "937080808": {
+ "message": "Content Recording: Recorded task is removed, so stop recording on display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"939638078": {
"message": "config_deviceTabletopRotations is not defined. Half-fold letterboxing will work inconsistently.",
"level": "WARN",
@@ -3517,6 +3505,12 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/DisplayPolicy.java"
},
+ "1145016093": {
+ "message": "Content Recording: Attempting to mirror self on %d",
+ "level": "WARN",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"1149424314": {
"message": "Unregister display organizer=%s uid=%d",
"level": "VERBOSE",
@@ -3745,12 +3739,6 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/TaskOrganizerController.java"
},
- "1401287081": {
- "message": "Handle incoming session on display %d, with a pre-existing session %s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecordingController.java"
- },
"1401295262": {
"message": "Mode default, asking user",
"level": "WARN",
@@ -3787,12 +3775,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "1444064727": {
- "message": "Unexpectedly null window container; unable to update recording for display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"1448683958": {
"message": "Override pending remote transitionSet=%b adapter=%s",
"level": "INFO",
@@ -3877,6 +3859,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "1546187372": {
+ "message": "Content Recording: Pause the recording session on display %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+ },
"1557732761": {
"message": "For Intent %s bringing to top: %s",
"level": "DEBUG",
@@ -3889,6 +3877,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "1563836923": {
+ "message": "Content Recording: Unable to record task since feature is disabled %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"1577579529": {
"message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
"level": "ERROR",
@@ -3907,12 +3901,6 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
- "1608402305": {
- "message": "Unable to start recording due to invalid region for display %d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_CONTENT_RECORDING",
- "at": "com\/android\/server\/wm\/ContentRecorder.java"
- },
"1610646518": {
"message": "Enqueueing pending finish: %s",
"level": "VERBOSE",
@@ -3973,6 +3961,12 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/InsetsStateController.java"
},
+ "1661414284": {
+ "message": "Content Recording: Unable to tell MediaProjectionManagerService about resizing the active projection: %s",
+ "level": "ERROR",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"1667162379": {
"message": "Creating Pending Transition: %s",
"level": "VERBOSE",
@@ -4021,6 +4015,12 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
},
+ "1712935427": {
+ "message": "Content Recording: Unable to start recording for display %d since the surface is not available.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"1720229827": {
"message": "Creating animation bounds layer",
"level": "INFO",
@@ -4051,6 +4051,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "1750878635": {
+ "message": "Content Recording: Provided surface for recording on display %d is not present, so do not update the surface",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"1756082882": {
"message": "Orientation change skips hidden %s",
"level": "VERBOSE",
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 24fea01..99bebb8 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -210,12 +210,16 @@
private static final Rgb.TransferParameters SRGB_TRANSFER_PARAMETERS =
new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4);
+
+ // HLG transfer with an SDR whitepoint of 203 nits
private static final Rgb.TransferParameters BT2020_HLG_TRANSFER_PARAMETERS =
- new Rgb.TransferParameters(2.0f, 2.0f, 1 / 0.17883277f,
- 0.28466892f, 0.5599107f, -11 / 12.0f, -3.0f, true);
+ new Rgb.TransferParameters(2.0, 2.0, 1 / 0.17883277, 0.28466892, 0.55991073,
+ -0.685490157, Rgb.TransferParameters.TYPE_HLGish);
+
+ // PQ transfer with an SDR whitepoint of 203 nits
private static final Rgb.TransferParameters BT2020_PQ_TRANSFER_PARAMETERS =
- new Rgb.TransferParameters(-107 / 128.0f, 1.0f, 32 / 2523.0f,
- 2413 / 128.0f, -2392 / 128.0f, 8192 / 1305.0f, -2.0f, true);
+ new Rgb.TransferParameters(-1.555223, 1.860454, 32 / 2523.0, 2413 / 128.0,
+ -2392 / 128.0, 8192 / 1305.0, Rgb.TransferParameters.TYPE_PQish);
// See static initialization block next to #get(Named)
private static final ColorSpace[] sNamedColorSpaces = new ColorSpace[Named.values().length];
@@ -1651,8 +1655,8 @@
BT2020_PRIMARIES,
ILLUMINANT_D65,
null,
- x -> transferHLGOETF(x),
- x -> transferHLGEOTF(x),
+ x -> transferHLGOETF(BT2020_HLG_TRANSFER_PARAMETERS, x),
+ x -> transferHLGEOTF(BT2020_HLG_TRANSFER_PARAMETERS, x),
0.0f, 1.0f,
BT2020_HLG_TRANSFER_PARAMETERS,
Named.BT2020_HLG.ordinal()
@@ -1663,8 +1667,8 @@
BT2020_PRIMARIES,
ILLUMINANT_D65,
null,
- x -> transferST2048OETF(x),
- x -> transferST2048EOTF(x),
+ x -> transferST2048OETF(BT2020_PQ_TRANSFER_PARAMETERS, x),
+ x -> transferST2048EOTF(BT2020_PQ_TRANSFER_PARAMETERS, x),
0.0f, 1.0f,
BT2020_PQ_TRANSFER_PARAMETERS,
Named.BT2020_PQ.ordinal()
@@ -1672,44 +1676,58 @@
sDataToColorSpaces.put(DataSpace.DATASPACE_BT2020_PQ, Named.BT2020_PQ.ordinal());
}
- private static double transferHLGOETF(double x) {
- double a = 0.17883277;
- double b = 0.28466892;
- double c = 0.55991073;
- double r = 0.5;
- return x > 1.0 ? a * Math.log(x - b) + c : r * Math.sqrt(x);
+ private static double transferHLGOETF(Rgb.TransferParameters params, double x) {
+ double sign = x < 0 ? -1.0 : 1.0;
+ x *= sign;
+
+ // Unpack the transfer params matching skia's packing & invert R, G, and a
+ final double R = 1.0 / params.a;
+ final double G = 1.0 / params.b;
+ final double a = 1.0 / params.c;
+ final double b = params.d;
+ final double c = params.e;
+ final double K = params.f + 1.0;
+
+ x /= K;
+ return sign * (x <= 1 ? R * Math.pow(x, G) : a * Math.log(x - b) + c);
}
- private static double transferHLGEOTF(double x) {
- double a = 0.17883277;
- double b = 0.28466892;
- double c = 0.55991073;
- double r = 0.5;
- return x <= 0.5 ? (x * x) / (r * r) : Math.exp((x - c) / a + b);
+ private static double transferHLGEOTF(Rgb.TransferParameters params, double x) {
+ double sign = x < 0 ? -1.0 : 1.0;
+ x *= sign;
+
+ // Unpack the transfer params matching skia's packing
+ final double R = params.a;
+ final double G = params.b;
+ final double a = params.c;
+ final double b = params.d;
+ final double c = params.e;
+ final double K = params.f + 1.0;
+
+ return K * sign * (x * R <= 1 ? Math.pow(x * R, G) : Math.exp((x - c) * a) + b);
}
- private static double transferST2048OETF(double x) {
- double m1 = (2610.0 / 4096.0) / 4.0;
- double m2 = (2523.0 / 4096.0) * 128.0;
- double c1 = (3424.0 / 4096.0);
- double c2 = (2413.0 / 4096.0) * 32.0;
- double c3 = (2392.0 / 4096.0) * 32.0;
+ private static double transferST2048OETF(Rgb.TransferParameters params, double x) {
+ double sign = x < 0 ? -1.0 : 1.0;
+ x *= sign;
- double tmp = Math.pow(x, m1);
- tmp = (c1 + c2 * tmp) / (1.0 + c3 * tmp);
- return Math.pow(tmp, m2);
+ double a = -params.a;
+ double b = params.d;
+ double c = 1.0 / params.f;
+ double d = params.b;
+ double e = -params.e;
+ double f = 1.0 / params.c;
+
+ double tmp = Math.max(a + b * Math.pow(x, c), 0);
+ return sign * Math.pow(tmp / (d + e * Math.pow(x, c)), f);
}
- private static double transferST2048EOTF(double x) {
- double m1 = (2610.0 / 4096.0) / 4.0;
- double m2 = (2523.0 / 4096.0) * 128.0;
- double c1 = (3424.0 / 4096.0);
- double c2 = (2413.0 / 4096.0) * 32.0;
- double c3 = (2392.0 / 4096.0) * 32.0;
+ private static double transferST2048EOTF(Rgb.TransferParameters pq, double x) {
+ double sign = x < 0 ? -1.0 : 1.0;
+ x *= sign;
- double tmp = Math.pow(Math.min(Math.max(x, 0.0), 1.0), 1.0 / m2);
- tmp = Math.max(tmp - c1, 0.0) / (c2 - c3 * tmp);
- return Math.pow(tmp, 1.0 / m1);
+ double tmp = Math.max(pq.a + pq.b * Math.pow(x, pq.c), 0);
+ return sign * Math.pow(tmp / (pq.d + pq.e * Math.pow(x, pq.c)), pq.f);
}
// Reciprocal piecewise gamma response
@@ -2276,6 +2294,10 @@
* </ul>
*/
public static class TransferParameters {
+
+ private static final double TYPE_PQish = -2.0;
+ private static final double TYPE_HLGish = -3.0;
+
/** Variable \(a\) in the equation of the EOTF described above. */
public final double a;
/** Variable \(b\) in the equation of the EOTF described above. */
@@ -2291,56 +2313,8 @@
/** Variable \(g\) in the equation of the EOTF described above. */
public final double g;
- private TransferParameters(double a, double b, double c, double d, double e,
- double f, double g, boolean nonCurveTransferParameters) {
- // nonCurveTransferParameters correspondes to a "special" transfer function
- if (!nonCurveTransferParameters) {
- if (Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(c)
- || Double.isNaN(d) || Double.isNaN(e) || Double.isNaN(f)
- || Double.isNaN(g)) {
- throw new IllegalArgumentException("Parameters cannot be NaN");
- }
-
- // Next representable float after 1.0
- // We use doubles here but the representation inside our native code
- // is often floats
- if (!(d >= 0.0 && d <= 1.0f + Math.ulp(1.0f))) {
- throw new IllegalArgumentException(
- "Parameter d must be in the range [0..1], " + "was " + d);
- }
-
- if (d == 0.0 && (a == 0.0 || g == 0.0)) {
- throw new IllegalArgumentException(
- "Parameter a or g is zero, the transfer function is constant");
- }
-
- if (d >= 1.0 && c == 0.0) {
- throw new IllegalArgumentException(
- "Parameter c is zero, the transfer function is constant");
- }
-
- if ((a == 0.0 || g == 0.0) && c == 0.0) {
- throw new IllegalArgumentException("Parameter a or g is zero,"
- + " and c is zero, the transfer function is constant");
- }
-
- if (c < 0.0) {
- throw new IllegalArgumentException(
- "The transfer function must be increasing");
- }
-
- if (a < 0.0 || g < 0.0) {
- throw new IllegalArgumentException(
- "The transfer function must be positive or increasing");
- }
- }
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
- this.e = e;
- this.f = f;
- this.g = g;
+ private static boolean isSpecialG(double g) {
+ return g == TYPE_PQish || g == TYPE_HLGish;
}
/**
@@ -2365,7 +2339,7 @@
* @throws IllegalArgumentException If the parameters form an invalid transfer function
*/
public TransferParameters(double a, double b, double c, double d, double g) {
- this(a, b, c, d, 0.0, 0.0, g, false);
+ this(a, b, c, d, 0.0, 0.0, g);
}
/**
@@ -2384,7 +2358,52 @@
*/
public TransferParameters(double a, double b, double c, double d, double e,
double f, double g) {
- this(a, b, c, d, e, f, g, false);
+ if (Double.isNaN(a) || Double.isNaN(b) || Double.isNaN(c)
+ || Double.isNaN(d) || Double.isNaN(e) || Double.isNaN(f)
+ || Double.isNaN(g)) {
+ throw new IllegalArgumentException("Parameters cannot be NaN");
+ }
+ if (!isSpecialG(g)) {
+ // Next representable float after 1.0
+ // We use doubles here but the representation inside our native code
+ // is often floats
+ if (!(d >= 0.0 && d <= 1.0f + Math.ulp(1.0f))) {
+ throw new IllegalArgumentException(
+ "Parameter d must be in the range [0..1], " + "was " + d);
+ }
+
+ if (d == 0.0 && (a == 0.0 || g == 0.0)) {
+ throw new IllegalArgumentException(
+ "Parameter a or g is zero, the transfer function is constant");
+ }
+
+ if (d >= 1.0 && c == 0.0) {
+ throw new IllegalArgumentException(
+ "Parameter c is zero, the transfer function is constant");
+ }
+
+ if ((a == 0.0 || g == 0.0) && c == 0.0) {
+ throw new IllegalArgumentException("Parameter a or g is zero,"
+ + " and c is zero, the transfer function is constant");
+ }
+
+ if (c < 0.0) {
+ throw new IllegalArgumentException(
+ "The transfer function must be increasing");
+ }
+
+ if (a < 0.0 || g < 0.0) {
+ throw new IllegalArgumentException(
+ "The transfer function must be positive or increasing");
+ }
+ }
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ this.e = e;
+ this.f = f;
+ this.g = g;
}
@SuppressWarnings("SimplifiableIfStatement")
@@ -2424,6 +2443,17 @@
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
+
+ /**
+ * @hide
+ */
+ private boolean isHLGish() {
+ return g == TYPE_HLGish;
+ }
+
+ private boolean isPQish() {
+ return g == TYPE_PQish;
+ }
}
@NonNull private final float[] mWhitePoint;
@@ -2460,11 +2490,10 @@
float e, float f, float g, float[] xyz);
private static DoubleUnaryOperator generateOETF(TransferParameters function) {
- boolean isNonCurveTransferParameters = function.equals(BT2020_HLG_TRANSFER_PARAMETERS)
- || function.equals(BT2020_PQ_TRANSFER_PARAMETERS);
- if (isNonCurveTransferParameters) {
- return function.f == 0.0 && function.g < 0.0 ? x -> transferHLGOETF(x)
- : x -> transferST2048OETF(x);
+ if (function.isHLGish()) {
+ return x -> transferHLGOETF(function, x);
+ } else if (function.isPQish()) {
+ return x -> transferST2048OETF(function, x);
} else {
return function.e == 0.0 && function.f == 0.0
? x -> rcpResponse(x, function.a, function.b,
@@ -2475,11 +2504,10 @@
}
private static DoubleUnaryOperator generateEOTF(TransferParameters function) {
- boolean isNonCurveTransferParameters = function.equals(BT2020_HLG_TRANSFER_PARAMETERS)
- || function.equals(BT2020_PQ_TRANSFER_PARAMETERS);
- if (isNonCurveTransferParameters) {
- return function.f == 0.0 && function.g < 0.0 ? x -> transferHLGEOTF(x)
- : x -> transferST2048EOTF(x);
+ if (function.isHLGish()) {
+ return x -> transferHLGEOTF(function, x);
+ } else if (function.isPQish()) {
+ return x -> transferST2048OETF(function, x);
} else {
return function.e == 0.0 && function.f == 0.0
? x -> response(x, function.a, function.b,
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 51f99ec..60898ef 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -914,6 +914,7 @@
case "image/gif":
case "image/heif":
case "image/heic":
+ case "image/avif":
case "image/bmp":
case "image/x-ico":
case "image/vnd.wap.wbmp":
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
index dcc12ac..7fc8310e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
@@ -214,7 +214,8 @@
openingWholeScreenBounds.union(target.screenSpaceBounds);
} else {
closingTargets.add(target);
- closingWholeScreenBounds.union(target.screenSpaceBounds);
+ // Union the start bounds since this may be the ClosingChanging animation.
+ closingWholeScreenBounds.union(target.startBounds);
}
}
diff --git a/libs/WindowManager/Shell/res/color-night/taskbar_background.xml b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml
index 9473cdd6..01df006 100644
--- a/libs/WindowManager/Shell/res/color-night/taskbar_background.xml
+++ b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml
@@ -16,5 +16,5 @@
-->
<!-- Should be the same as in packages/apps/Launcher3/res/color-night-v31/taskbar_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_500" android:lStar="15" />
+ <item android:color="@android:color/system_neutral1_500" android:lStar="20" />
</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/taskbar_background.xml b/libs/WindowManager/Shell/res/color/taskbar_background.xml
index 0e165fc..876ee02 100644
--- a/libs/WindowManager/Shell/res/color/taskbar_background.xml
+++ b/libs/WindowManager/Shell/res/color/taskbar_background.xml
@@ -16,5 +16,5 @@
-->
<!-- Should be the same as in packages/apps/Launcher3/res/color-v31/taskbar_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_500" android:lStar="95" />
+ <item android:color="@android:color/system_neutral1_500" android:lStar="98" />
</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
index 27e0b18..5d77713 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
@@ -14,13 +14,12 @@
~ 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="@color/decor_button_dark_color">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<group android:translateY="8.0">
<path
- android:fillColor="@android:color/white" android:pathData="M3,5V3H21V5Z"/>
+ android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
</group>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
new file mode 100644
index 0000000..0225949
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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 android:shape="rectangle"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#bf309fb5" />
+ <corners android:radius="20dp" />
+ <stroke android:width="1dp" color="#A00080FF"/>
+</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
new file mode 100644
index 0000000..3e0297a
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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 android:height="24dp" android:tint="#000000"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/black" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/reachability_education_ic_left_hand.xml b/libs/WindowManager/Shell/res/drawable/reachability_education_ic_left_hand.xml
new file mode 100644
index 0000000..c400dc6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/reachability_education_ic_left_hand.xml
@@ -0,0 +1,699 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="30dp" android:width="30dp" android:viewportHeight="30"
+ android:viewportWidth="30">
+ <group android:name="_R_G" android:scaleX="-1" android:translateX="30">
+ <group android:name="_R_G_L_0_G" android:translateX="-135" android:translateY="-135"
+ android:pivotX="150" android:pivotY="150" android:scaleX="0.1"
+ android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="134.624"
+ android:translateY="87.514" android:pivotX="11.625" android:pivotY="6.39"
+ android:scaleX="10" android:scaleY="10">
+ <group android:name="_R_G_L_0_G_L_1_G_D_0_P_0_G_0_T_0"
+ android:translateX="11.625" android:translateY="6.464"
+ android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillColor="@color/letterbox_reachability_education_item_color"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M-1.54 5.39 C-3.87,4.71 -5.49,2.54 -5.49,0.11 C-5.49,-2.92 -3.03,-5.38 0,-5.38 C3.03,-5.38 5.49,-2.92 5.49,0.11 C5.49,2.11 4.41,3.95 2.66,4.92 C2.66,4.92 1.69,3.17 1.69,3.17 C2.8,2.55 3.49,1.38 3.49,0.11 C3.49,-1.82 1.93,-3.38 0,-3.38 C-1.93,-3.38 -3.49,-1.82 -3.49,0.11 C-3.49,1.65 -2.46,3.03 -0.98,3.47 C-0.98,3.47 -1.54,5.39 -1.54,5.39c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="138"
+ android:translateY="138" android:pivotX="12" android:pivotY="12"
+ android:scaleX="10" android:scaleY="10">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillColor="@color/letterbox_reachability_education_item_color"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="fillAlpha" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="750" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="1083" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="2250" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="2583" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="3750" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="4083" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="5250" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="5583" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="1083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="1083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="2250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="2250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="2583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="2583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="3750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="3750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="4083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="4083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="5250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="5250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="5583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="5583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="500"
+ android:startOffset="0"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="500"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="750"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="833"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="1083"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="1167"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="2000"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="2250"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="2333"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="2583"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="2667"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="3500"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="3750"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="3833"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="4083"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="4167"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="5000"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="5250"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="5333"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="5583"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="6000"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/libs/WindowManager/Shell/res/drawable/reachability_education_ic_right_hand.xml b/libs/WindowManager/Shell/res/drawable/reachability_education_ic_right_hand.xml
new file mode 100644
index 0000000..a807a77
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/reachability_education_ic_right_hand.xml
@@ -0,0 +1,699 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="30dp" android:width="30dp" android:viewportHeight="30"
+ android:viewportWidth="30">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_0_G" android:translateX="-135" android:translateY="-135"
+ android:pivotX="150" android:pivotY="150" android:scaleX="0.1"
+ android:scaleY="0.1">
+ <group android:name="_R_G_L_0_G_L_1_G" android:translateX="134.624"
+ android:translateY="87.514" android:pivotX="11.625" android:pivotY="6.39"
+ android:scaleX="10" android:scaleY="10">
+ <group android:name="_R_G_L_0_G_L_1_G_D_0_P_0_G_0_T_0"
+ android:translateX="11.625" android:translateY="6.464"
+ android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillColor="@color/letterbox_reachability_education_item_color"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M-1.54 5.39 C-3.87,4.71 -5.49,2.54 -5.49,0.11 C-5.49,-2.92 -3.03,-5.38 0,-5.38 C3.03,-5.38 5.49,-2.92 5.49,0.11 C5.49,2.11 4.41,3.95 2.66,4.92 C2.66,4.92 1.69,3.17 1.69,3.17 C2.8,2.55 3.49,1.38 3.49,0.11 C3.49,-1.82 1.93,-3.38 0,-3.38 C-1.93,-3.38 -3.49,-1.82 -3.49,0.11 C-3.49,1.65 -2.46,3.03 -0.98,3.47 C-0.98,3.47 -1.54,5.39 -1.54,5.39c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G" android:translateX="138"
+ android:translateY="138" android:pivotX="12" android:pivotY="12"
+ android:scaleX="10" android:scaleY="10">
+ <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillColor="@color/letterbox_reachability_education_item_color"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="fillAlpha" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="750" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="1083" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="2250" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="2583" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="3750" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="4083" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="5250" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="0.1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="fillAlpha" android:duration="83"
+ android:startOffset="5583" android:valueFrom="0.1"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator
+ android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_1_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="500"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="1083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="1083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="1167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="2000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="2250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="2250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="2333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="2583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="2583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="2667" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="3500" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="3750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="3750" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="3833" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="4083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="4083" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="833"
+ android:startOffset="4167" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="5000" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="5250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="5250" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="5333" android:valueFrom="1"
+ android:valueTo="1.4000000000000001" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="5583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="5583" android:valueFrom="1.4000000000000001"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.999,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="500"
+ android:startOffset="0"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="500"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="750"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="833"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="1083"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="1167"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="2000"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="2250"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="2333"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="2583"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="2667"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="3500"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="3750"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="3833"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="4083"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="833"
+ android:startOffset="4167"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="5000"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="5250"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="250"
+ android:startOffset="5333"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="5583"
+ android:valueFrom="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,8 14.13,8 C14.13,7.3 13.88,6.71 13.4,6.23 C12.92,5.74 12.33,5.5 11.63,5.5 C10.93,5.5 10.33,5.74 9.85,6.23 C9.37,6.71 9.13,7.3 9.13,8 C9.13,8 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,8 11.13,8 C11.13,7.85 11.17,7.73 11.26,7.64 C11.35,7.55 11.48,7.5 11.63,7.5 C11.78,7.5 11.9,7.55 11.99,7.64 C12.08,7.73 12.13,7.85 12.13,8 C12.13,8 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueTo="M19.81 13.64 C19.62,13.23 19.33,12.93 18.93,12.75 C18.93,12.75 15.23,10.95 15.23,10.95 C15.16,10.9 15.09,10.86 15.01,10.84 C14.99,10.83 14.96,10.83 14.94,10.83 C14.88,10.81 14.83,10.8 14.78,10.8 C14.78,10.8 14.13,10.8 14.13,10.8 C14.13,10.8 14.13,8.9 14.13,8.9 C14.13,8.9 14.13,6.5 14.13,6.5 C14.13,5.8 13.88,5.21 13.4,4.72 C12.92,4.24 12.33,4 11.63,4 C10.93,4 10.33,4.24 9.85,4.72 C9.37,5.21 9.13,5.8 9.13,6.5 C9.13,6.5 9.13,8.95 9.13,8.95 C9.13,8.95 9.13,11.4 9.13,11.4 C9.13,11.4 9.13,14.65 9.13,14.65 C9.13,14.65 7.18,14.2 7.18,14.2 C6.86,14.12 6.56,14.14 6.26,14.26 C5.97,14.39 5.71,14.57 5.48,14.8 C5.48,14.8 4.08,16.25 4.08,16.25 C4.08,16.25 9.23,21.4 9.23,21.4 C9.41,21.58 9.63,21.73 9.88,21.84 C10.13,21.95 10.39,22 10.68,22 C10.68,22 17.08,22 17.08,22 C17.56,22 17.99,21.85 18.38,21.54 C18.76,21.23 18.99,20.83 19.08,20.35 C19.08,20.35 19.98,14.9 19.98,14.9 C20.06,14.47 20,14.05 19.81,13.64c M17.08 20 C17.08,20 10.68,20 10.68,20 C10.68,20 6.88,16.2 6.88,16.2 C6.88,16.2 11.13,17.1 11.13,17.1 C11.13,17.1 11.13,6.5 11.13,6.5 C11.13,6.35 11.17,6.23 11.26,6.14 C11.35,6.05 11.48,6 11.63,6 C11.78,6 11.9,6.05 11.99,6.14 C12.08,6.23 12.13,6.35 12.13,6.5 C12.13,6.5 12.13,12.5 12.13,12.5 C12.13,12.5 13.88,12.5 13.88,12.5 C13.88,12.5 18.02,14.55 18.02,14.55 C18.02,14.55 17.08,20 17.08,20c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="6000"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
new file mode 100644
index 0000000..35562b6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
@@ -0,0 +1,93 @@
+<?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.
+ -->
+<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/desktop_mode_caption"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:background="@drawable/desktop_mode_decor_title">
+
+ <LinearLayout
+ android:id="@+id/open_menu_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:clickable="true"
+ android:focusable="true"
+ android:paddingStart="8dp"
+ android:background="?android:selectableItemBackgroundBorderless">
+
+ <ImageView
+ android:id="@+id/application_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_margin="4dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/app_icon_text" />
+
+ <TextView
+ android:id="@+id/application_name"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:minWidth="80dp"
+ android:textColor="@color/desktop_mode_caption_app_name_dark"
+ android:textSize="14sp"
+ android:textFontWeight="500"
+ android:gravity="center_vertical"
+ android:layout_weight="1"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ tools:text="Gmail"/>
+
+ <ImageButton
+ android:id="@+id/expand_menu_button"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:padding="4dp"
+ android:contentDescription="@string/collapse_menu_text"
+ android:src="@drawable/ic_baseline_expand_more_24"
+ android:tint="@color/desktop_mode_caption_expand_button_dark"
+ android:background="@null"
+ android:scaleType="fitCenter"
+ android:clickable="false"
+ android:focusable="false"
+ android:layout_gravity="center_vertical"/>
+
+ </LinearLayout>
+
+ <View
+ android:id="@+id/caption_handle"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ android:id="@+id/close_window"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:padding="4dp"
+ android:layout_marginEnd="8dp"
+ android:contentDescription="@string/close_button_text"
+ android:src="@drawable/decor_close_button_dark"
+ android:scaleType="fitCenter"
+ android:gravity="end"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:tint="@color/desktop_mode_caption_close_button_dark"/>
+</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
index f9aeb6a..ac13eae 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
@@ -50,7 +50,7 @@
android:layout_marginEnd="10dp"
android:contentDescription="@string/collapse_menu_text"
android:layout_alignParentEnd="true"
- android:background="@drawable/caption_collapse_menu_button"
+ android:background="@drawable/ic_baseline_expand_more_24"
android:layout_centerVertical="true"/>
</RelativeLayout>
<LinearLayout
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
similarity index 67%
rename from libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
rename to libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
index 29cf151..5ab159c 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
@@ -16,26 +16,21 @@
-->
<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/desktop_mode_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@drawable/desktop_mode_decor_title">
- <Button
- style="@style/CaptionButtonStyle"
- android:id="@+id/back_button"
- android:contentDescription="@string/back_button_text"
- android:background="@drawable/decor_back_button_dark"/>
- <Button
+
+ <ImageButton
android:id="@+id/caption_handle"
android:layout_width="128dp"
- android:layout_height="32dp"
- android:layout_margin="5dp"
+ android:layout_height="42dp"
android:contentDescription="@string/handle_text"
- android:background="@drawable/decor_handle_dark"/>
- <Button
- style="@style/CaptionButtonStyle"
- android:id="@+id/close_window"
- android:contentDescription="@string/close_button_text"
- android:background="@drawable/decor_close_button_dark"/>
+ android:src="@drawable/decor_handle_dark"
+ tools:tint="@color/desktop_mode_caption_handle_bar_dark"
+ android:scaleType="fitXY"
+ android:background="?android:selectableItemBackground"/>
+
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml b/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml
new file mode 100644
index 0000000..1e36fb6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<com.android.wm.shell.compatui.ReachabilityEduLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:focusable="false"
+ android:focusableInTouchMode="false"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.wm.shell.compatui.ReachabilityEduHandLayout
+ style="@style/ReachabilityEduHandLayout"
+ android:text="@string/letterbox_reachability_reposition_text"
+ app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
+ android:layout_gravity="center_horizontal|top"
+ android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
+ android:id="@+id/reachability_move_up_button"
+ android:maxWidth="@dimen/letterbox_reachability_education_item_width"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <com.android.wm.shell.compatui.ReachabilityEduHandLayout
+ style="@style/ReachabilityEduHandLayout"
+ android:text="@string/letterbox_reachability_reposition_text"
+ app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
+ android:layout_gravity="center_vertical|right"
+ android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
+ android:id="@+id/reachability_move_right_button"
+ android:maxWidth="@dimen/letterbox_reachability_education_item_width"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+
+ <com.android.wm.shell.compatui.ReachabilityEduHandLayout
+ style="@style/ReachabilityEduHandLayout"
+ android:text="@string/letterbox_reachability_reposition_text"
+ app:drawableTopCompat="@drawable/reachability_education_ic_left_hand"
+ android:layout_gravity="center_vertical|left"
+ android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
+ android:id="@+id/reachability_move_left_button"
+ android:maxWidth="@dimen/letterbox_reachability_education_item_width"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <com.android.wm.shell.compatui.ReachabilityEduHandLayout
+ style="@style/ReachabilityEduHandLayout"
+ android:text="@string/letterbox_reachability_reposition_text"
+ app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
+ android:id="@+id/reachability_move_down_button"
+ android:maxWidth="@dimen/letterbox_reachability_education_item_width"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+</com.android.wm.shell.compatui.ReachabilityEduLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 0897712..848f28c 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Beweeg na regs onder"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-instellings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Maak borrel toe"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Moenie borrels wys nie"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Moenie dat gesprek \'n borrel word nie"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Klets met borrels"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nuwe gesprekke verskyn as swerwende ikone, of borrels Tik op borrel om dit oop te maak. Sleep om dit te skuif."</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index bc58e20..9ed281f 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ታችኛውን ቀኝ ያንቀሳቅሱ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"የ<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ቅንብሮች"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"አረፋን አሰናብት"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ዓረፋ አትፍጠር"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ውይይቶችን በአረፋ አታሳይ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"አረፋዎችን በመጠቀም ይወያዩ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"አዲስ ውይይቶች እንደ ተንሳፋፊ አዶዎች ወይም አረፋዎች ሆነው ይታያሉ። አረፋን ለመክፈት መታ ያድርጉ። ለመውሰድ ይጎትቱት።"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 2aaf924..a8480eb 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"তলৰ সোঁফালে নিয়ক"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ছেটিং"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"বাবল অগ্ৰাহ্য কৰক"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"বাবল কৰাটো বন্ধ কৰক"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"বাৰ্তালাপ বাবল নকৰিব"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles ব্যৱহাৰ কৰি চাট কৰক"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"নতুন বাৰ্তালাপ উপঙি থকা চিহ্নসমূহ অথবা bubbles হিচাপে প্ৰদর্শিত হয়। Bubbles খুলিবলৈ টিপক। এইটো স্থানান্তৰ কৰিবলৈ টানি নিয়ক।"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index ad6e618..b158cdd 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Aşağıya sağa köçürün"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Yumrucuğu ləğv edin"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Yumrucuqları dayandırın"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Söhbəti yumrucuqda göstərmə"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Yumrucuqlardan istifadə edərək söhbət edin"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Yeni söhbətlər üzən nişanlar və ya yumrucuqlar kimi görünür. Yumrucuğu açmaq üçün toxunun. Hərəkət etdirmək üçün sürüşdürün."</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 1dd09f5..954d34fd 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premesti dole desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Bez oblačića"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne koristi oblačiće za konverzaciju"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Ćaskajte u oblačićima"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index b5d4eb1..a7757c6 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Преместване долу вдясно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Настройки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Отхвърляне на балончетата"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Без балончета"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Без балончета за разговора"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Чат с балончета"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новите разговори се показват като плаващи икони, или балончета. Докоснете балонче, за да го отворите, или го плъзнете, за да го преместите."</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 5c95f9e..f3f80b8 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"নিচে ডান দিকে সরান"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> সেটিংস"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"বাবল খারিজ করুন"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"বাবল করা বন্ধ করুন"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"কথোপকথন বাবল হিসেবে দেখাবে না"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"বাবল ব্যবহার করে চ্যাট করুন"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"নতুন কথোপকথন ভেসে থাকা আইকন বা বাবল হিসেবে দেখানো হয়। বাবল খুলতে ট্যাপ করুন। সেটি সরাতে ধরে টেনে আনুন।"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index f9ff29c..e7fa212 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pomjerite dolje desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Zaustavi oblačiće"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nemoj prikazivati razgovor u oblačićima"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatajte koristeći oblačiće"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi razgovori se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da otvorite oblačić. Prevucite da ga premjestite."</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index b54e60d..1021667 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mou a baix a la dreta"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configuració de l\'aplicació <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignora la bombolla"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"No mostris com a bombolla"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostris la conversa com a bombolla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Xateja amb bombolles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Les converses noves es mostren com a icones flotants o bombolles. Toca per obrir una bombolla. Arrossega-la per moure-la."</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 11090e0..b2b76197 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Nach unten rechts verschieben"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Einstellungen für <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubble schließen"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Keine Bubbles zulassen"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Unterhaltung nicht als Bubble anzeigen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles zum Chatten verwenden"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, „Bubbles“ genannt. Wenn du eine Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 1eca52a..a09a647 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Μετακίνηση κάτω δεξιά"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Ρυθμίσεις <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Παράβλ. για συννεφ."</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Να μην εμφανίζει συννεφάκια"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Να μην γίνει προβολή της συζήτησης σε συννεφάκια."</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Συζητήστε χρησιμοποιώντας συννεφάκια."</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Οι νέες συζητήσεις εμφανίζονται ως κινούμενα εικονίδια ή συννεφάκια. Πατήστε για να ανοίξετε το συννεφάκι. Σύρετε για να το μετακινήσετε."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 8493434..0a0b30d 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index e9c78fc..33f5333 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 8493434..0a0b30d 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 8493434..0a0b30d 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 466a2bf..69823f9 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index b017591..b7b31f4 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Ubicar abajo a la derecha"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Descartar burbuja"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"No mostrar burbujas"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostrar la conversación en burbuja"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat con burbujas"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como elementos flotantes o burbujas. Presiona para abrir la burbuja. Arrástrala para moverla."</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 986a2c8..5ef402c 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover abajo a la derecha"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Cerrar burbuja"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"No mostrar burbujas"</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 llamados \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index b84c4f2..e083be4 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Teisalda alla paremale"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Sule mull"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ära kuva mulle"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ära kuva vestlust mullina"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Vestelge mullide abil"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Uued vestlused kuvatakse hõljuvate ikoonidena ehk mullidena. Puudutage mulli avamiseks. Lohistage mulli, et seda liigutada."</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index a297219..e0922e4 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Eraman behealdera, eskuinetara"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikazioaren ezarpenak"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Baztertu burbuila"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ez erakutsi burbuilarik"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ez erakutsi elkarrizketak burbuila gisa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Txateatu burbuilen bidez"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Elkarrizketa berriak ikono gainerakor edo burbuila gisa agertzen dira. Sakatu burbuila irekitzeko. Arrasta ezazu mugitzeko."</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index b379428..e847f6e 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"انتقال به پایین سمت چپ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"تنظیمات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"رد کردن حبابک"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"حبابک نشان داده نشود"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"مکالمه در حباب نشان داده نشود"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"گپ بااستفاده از حبابکها"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمههای جدید بهصورت نمادهای شناور یا حبابکها نشان داده میشوند. برای باز کردن حبابکها ضربه بزنید. برای جابهجایی، آن را بکشید."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 7e3eae0..c86711e 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Déplacer en bas à droite"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Fermer la bulle"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Désactiver les info-bulles"</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 de bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index f3a3162..8de29c1 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"નીચે જમણે ખસેડો"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> સેટિંગ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"બબલને છોડી દો"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"બબલ બતાવશો નહીં"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"વાતચીતને બબલ કરશો નહીં"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"બબલનો ઉપયોગ કરીને ચૅટ કરો"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"નવી વાતચીત ફ્લોટિંગ આઇકન અથવા બબલ જેવી દેખાશે. બબલને ખોલવા માટે ટૅપ કરો. તેને ખસેડવા માટે ખેંચો."</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 134fb97..d71824f 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"सबसे नीचे दाईं ओर ले जाएं"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> की सेटिंग"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल खारिज करें"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"बबल होने से रोकें"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"बातचीत को बबल न करें"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल्स का इस्तेमाल करके चैट करें"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नई बातचीत फ़्लोटिंग आइकॉन या बबल्स की तरह दिखेंगी. बबल को खोलने के लिए टैप करें. इसे एक जगह से दूसरी जगह ले जाने के लिए खींचें और छोड़ें."</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index f0a8dee..de4cac2 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premjestite u donji desni kut"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ne prikazuj oblačiće"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Zaustavi razgovor u oblačićima"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Oblačići u chatu"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi razgovori pojavljuju se kao pomične ikone ili oblačići. Dodirnite za otvaranje oblačića. Povucite da biste ga premjestili."</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index ea43370..667464f 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Áthelyezés le és jobbra"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> beállításai"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Buborék elvetése"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ne jelenjen meg buborékban"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne jelenjen meg a beszélgetés buborékban"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Buborékokat használó csevegés"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Az új beszélgetések lebegő ikonként, vagyis buborékként jelennek meg. A buborék megnyitásához koppintson rá. Áthelyezéshez húzza a kívánt helyre."</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index df2f2df..8cd0bc5 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pindahkan ke kanan bawah"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Setelan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Tutup balon"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Berhenti menampilkan balon"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Jangan gunakan percakapan balon"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat dalam tampilan balon"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Percakapan baru muncul sebagai ikon mengambang, atau balon. Ketuk untuk membuka balon. Tarik untuk memindahkannya."</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index a6301b3..ae5e182 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Færðu neðst til hægri"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Stillingar <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Loka blöðru"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ekki sýna blöðrur"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ekki setja samtal í blöðru"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Spjalla með blöðrum"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Ný samtöl birtast sem fljótandi tákn eða blöðrur. Ýttu til að opna blöðru. Dragðu hana til að færa."</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index b925970..9963ace 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"העברה לפינה הימנית התחתונה"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"הגדרות <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"סגירת בועה"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ללא בועות"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"אין להציג בועות לשיחה"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"לדבר בבועות"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"שיחות חדשות מופיעות כסמלים צפים, או בועות. יש להקיש כדי לפתוח בועה. יש לגרור כדי להזיז אותה."</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index e1d1de4..02cf02f 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"გადაანაცვ. ქვემოთ და მარჯვნივ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-ის პარამეტრები"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ბუშტის დახურვა"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ბუშტის გამორთვა"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"აიკრძალოს საუბრის ბუშტები"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ჩეთი ბუშტების გამოყენებით"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ახალი საუბრები გამოჩნდება როგორც მოტივტივე ხატულები ან ბუშტები. შეეხეთ ბუშტის გასახსნელად. გადაიტანეთ ჩავლებით."</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index de952ad..b60c231 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төменгі оң жаққа жылжыту"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлері"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Қалқымалы хабарды жабу"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Қалқыма хабарлар көрсетпеу"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Әңгіменің қалқыма хабары көрсетілмесін"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Қалқыма хабарлар арқылы сөйлесу"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңа әңгімелер қалқыма белгішелер немесе хабарлар түрінде көрсетіледі. Қалқыма хабарды ашу үшін түртіңіз. Жылжыту үшін сүйреңіз."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 762f3a8..29ff6c3 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ផ្លាស់ទីទៅផ្នែកខាងក្រោមខាងស្ដាំ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"ការកំណត់ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ច្រានចោលពពុះ"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"កុំបង្ហាញពពុះ"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"កុំបង្ហាញការសន្ទនាជាពពុះ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ជជែកដោយប្រើពពុះ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ការសន្ទនាថ្មីៗបង្ហាញជាពពុះ ឬរូបអណ្ដែត។ ចុច ដើម្បីបើកពពុះ។ អូស ដើម្បីផ្លាស់ទីពពុះនេះ។"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index f9582ff..a67e066 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ಕೆಳಗಿನ ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ಬಬಲ್ ವಜಾಗೊಳಿಸಿ"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ಬಬಲ್ ತೋರಿಸಬೇಡಿ"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ಸಂಭಾಷಣೆಯನ್ನು ಬಬಲ್ ಮಾಡಬೇಡಿ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ಬಬಲ್ಸ್ ಬಳಸಿ ಚಾಟ್ ಮಾಡಿ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ಹೊಸ ಸಂಭಾಷಣೆಗಳು ತೇಲುವ ಐಕಾನ್ಗಳು ಅಥವಾ ಬಬಲ್ಸ್ ಆಗಿ ಗೋಚರಿಸುತ್ತವೆ. ಬಬಲ್ ತೆರೆಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಅದನ್ನು ಡ್ರ್ಯಾಗ್ ಮಾಡಲು ಎಳೆಯಿರಿ."</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 2b30aab..0b88d7a 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"오른쪽 하단으로 이동"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> 설정"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"대화창 닫기"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"도움말 풍선 중지"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"대화를 대화창으로 표시하지 않기"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"대화창으로 채팅하기"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"새로운 대화가 플로팅 아이콘인 대화창으로 표시됩니다. 대화창을 열려면 탭하세요. 드래그하여 이동할 수 있습니다."</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 27b89b7..683a903 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төмөнкү оң жакка жылдыруу"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлери"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Калкып чыкма билдирмени жабуу"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Калкып чыкма билдирмелер көрсөтүлбөсүн"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Калкып чыкма билдирмелер аркылуу маектешүү"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 6aae84c..c311410 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ຍ້າຍຂວາລຸ່ມ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"ການຕັ້ງຄ່າ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ປິດຟອງໄວ້"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ບໍ່ຕ້ອງສະແດງ bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ຢ່າໃຊ້ຟອງໃນການສົນທະນາ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ສົນທະນາໂດຍໃຊ້ຟອງ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ການສົນທະນາໃໝ່ຈະປາກົດເປັນໄອຄອນ ຫຼື ຟອງແບບລອຍ. ແຕະເພື່ອເປີດຟອງ. ລາກເພື່ອຍ້າຍມັນ."</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 3f2a17b..be8e247 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Perkelti į apačią dešinėje"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ nustatymai"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Atsisakyti burbulo"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Nerodyti debesėlių"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nerodyti pokalbio burbule"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Pokalbis naudojant burbulus"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nauji pokalbiai rodomi kaip slankiosios piktogramos arba burbulai. Palieskite, kad atidarytumėte burbulą. Vilkite, kad perkeltumėte."</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index ae85c1f..d6a1f16 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pārvietot apakšpusē pa labi"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Nerādīt burbuli"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Pārtraukt burbuļu rādīšanu"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nerādīt sarunu burbuļos"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Tērzēšana, izmantojot burbuļus"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Jaunas sarunas tiek rādītas kā peldošas ikonas vai burbuļi. Pieskarieties, lai atvērtu burbuli. Velciet, lai to pārvietotu."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 133eedb1..385dc32 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести долу десно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Поставки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Отфрли балонче"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Не прикажувај балонче"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не прикажувај го разговорот во балончиња"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Разговор во балончиња"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новите разговори ќе се појавуваат како лебдечки икони или балончиња. Допрете за отворање на балончето. Повлечете за да го преместите."</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index c38609e..561806c 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ചുവടെ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ക്രമീകരണം"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ബബിൾ ഡിസ്മിസ് ചെയ്യൂ"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ബബിൾ ചെയ്യരുത്"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"സംഭാഷണം ബബിൾ ചെയ്യരുത്"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ബബിളുകൾ ഉപയോഗിച്ച് ചാറ്റ് ചെയ്യുക"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"പുതിയ സംഭാഷണങ്ങൾ ഫ്ലോട്ടിംഗ് ഐക്കണുകളോ ബബിളുകളോ ആയി ദൃശ്യമാവുന്നു. ബബിൾ തുറക്കാൻ ടാപ്പ് ചെയ്യൂ. ഇത് നീക്കാൻ വലിച്ചിടുക."</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index e0b4141..c0c9eb7 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Баруун доош зөөх"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-н тохиргоо"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Бөмбөлгийг хаах"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Бөмбөлөг бүү харуул"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Харилцан яриаг бүү бөмбөлөг болго"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Бөмбөлөг ашиглан чатлаарай"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Шинэ харилцан яриа нь хөвөгч дүрс тэмдэг эсвэл бөмбөлөг хэлбэрээр харагддаг. Бөмбөлгийг нээхийн тулд товшино уу. Түүнийг зөөхийн тулд чирнэ үү."</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index f85fe1b..a18d1f1 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"तळाशी उजवीकडे हलवा"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> सेटिंग्ज"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल डिसमिस करा"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"बबल दाखवू नका"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"संभाषणाला बबल करू नका"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल वापरून चॅट करा"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नवीन संभाषणे फ्लोटिंग आयकन किंवा बबल म्हणून दिसतात. बबल उघडण्यासाठी टॅप करा. हे हलवण्यासाठी ड्रॅग करा."</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
index 8a89779..89654d0 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
@@ -24,7 +24,7 @@
<string name="pip_move" msgid="158770205886688553">"हलवा"</string>
<string name="pip_expand" msgid="1051966011679297308">"विस्तार करा"</string>
<string name="pip_collapse" msgid="3903295106641385962">"कोलॅप्स करा"</string>
- <string name="pip_edu_text" msgid="7930546669915337998">"नियंत्रणांसाठी "<annotation icon="home_icon">"होम"</annotation>" दोनदा दाबा"</string>
+ <string name="pip_edu_text" msgid="7930546669915337998">"नियंत्रणांसाठी "<annotation icon="home_icon">"होम"</annotation>" दोनदा प्रेस करा"</string>
<string name="a11y_pip_menu_entered" msgid="5106343214776801614">"चित्रात-चित्र मेनू."</string>
<string name="a11y_action_pip_move_left" msgid="6612980937817141583">"डावीकडे हलवा"</string>
<string name="a11y_action_pip_move_right" msgid="1119409122645529936">"उजवीकडे हलवा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 6f22599..b891c59 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Alihkan ke bawah sebelah kanan"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Tetapan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ketepikan gelembung"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Hentikan gelembung"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Jangan jadikan perbualan dalam bentuk gelembung"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bersembang menggunakan gelembung"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Perbualan baharu muncul sebagai ikon terapung atau gelembung. Ketik untuk membuka gelembung. Seret untuk mengalihkan gelembung tersebut."</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 5a88cd0..2b6adc1 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ညာအောက်ခြေသို့ ရွှေ့ပါ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ဆက်တင်များ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ပူဖောင်းကွက် ပယ်ရန်"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ပူဖောင်းကွက် မပြပါနှင့်"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"စကားဝိုင်းကို ပူဖောင်းကွက် မပြုလုပ်ပါနှင့်"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ပူဖောင်းကွက် သုံး၍ ချတ်လုပ်ခြင်း"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"စကားဝိုင်းအသစ်များကို မျောနေသည့် သင်္ကေတများ သို့မဟုတ် ပူဖောင်းကွက်များအဖြစ် မြင်ရပါမည်။ ပူဖောင်းကွက်ကိုဖွင့်ရန် တို့ပါ။ ရွှေ့ရန် ၎င်းကို ဖိဆွဲပါ။"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 6b164e9..3afa9fb 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"पुछारमा दायाँतिर सार्नुहोस्"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> का सेटिङहरू"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल खारेज गर्नुहोस्"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"बबल नदेखाइयोस्"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"वार्तालाप बबलको रूपमा नदेखाइयोस्"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबलहरू प्रयोग गरी कुराकानी गर्नुहोस्"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नयाँ वार्तालापहरू तैरने आइकन वा बबलका रूपमा देखिन्छन्। बबल खोल्न ट्याप गर्नुहोस्। बबल सार्न सो बबललाई ड्र्याग गर्नुहोस्।"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 2d02ed5..21e89c3 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Naar rechtsonder verplaatsen"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Instellingen voor <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubbel sluiten"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Niet als bubbel tonen"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Gesprekken niet in bubbels tonen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatten met bubbels"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nieuwe gesprekken worden als zwevende iconen of bubbels getoond. Tik om een bubbel te openen. Sleep om een bubbel te verplaatsen."</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 6400283..e781f45 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ତଳ ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ସେଟିଂସ୍"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ବବଲ୍ ଖାରଜ କରନ୍ତୁ"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ବବଲ କରନ୍ତୁ ନାହିଁ"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ବାର୍ତ୍ତାଳାପକୁ ବବଲ୍ କରନ୍ତୁ ନାହିଁ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ବବଲଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି ଚାଟ୍ କରନ୍ତୁ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ନୂଆ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଫ୍ଲୋଟିଂ ଆଇକନ୍ କିମ୍ବା ବବଲ୍ ଭାବେ ଦେଖାଯିବ। ବବଲ୍ ଖୋଲିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଏହାକୁ ମୁଭ୍ କରିବାକୁ ଟାଣନ୍ତୁ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 680bd5d..ef7773b9 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Przenieś w prawy dolny róg"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – ustawienia"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Zamknij dymek"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Nie twórz dymków"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nie wyświetlaj rozmowy jako dymka"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Czatuj, korzystając z dymków"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index c30b6f1..b034990 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover para canto inferior direito"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dispensar balão"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Parar de mostrar balões"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não criar balões de conversa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse usando balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 00f4aa0..c739ba0 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover parte inferior direita"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Definições de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignorar balão"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Não apresentar balões"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não apresentar a conversa em balões"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse no chat através de balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"As novas conversas aparecem como ícones flutuantes ou balões. Toque para abrir o balão. Arraste para o mover."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index c30b6f1..b034990 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover para canto inferior direito"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dispensar balão"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Parar de mostrar balões"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não criar balões de conversa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse usando balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 4cfb1fa..cbe11dd 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mută în dreapta jos"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Închide balonul"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Nu afișa bule"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nu afișa conversația în balon"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat cu baloane"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Conversațiile noi apar ca pictograme flotante sau baloane. Atinge pentru a deschide balonul. Trage pentru a-l muta."</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 741a5d1..7602282 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Перенести в правый нижний угол"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: настройки"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Скрыть всплывающий чат"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Отключить всплывающие подсказки"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не показывать всплывающий чат для разговора"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Всплывающие чаты"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новые разговоры будут появляться в виде плавающих значков, или всплывающих чатов. Чтобы открыть чат, нажмите на него, а чтобы переместить – перетащите."</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 4b89ab1..c908184 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Presunúť doprava nadol"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Nastavenia aplikácie <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Zavrieť bublinu"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Nezobrazovať bubliny"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nezobrazovať konverzáciu ako bublinu"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Čet pomocou bublín"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nové konverzácie sa zobrazujú ako plávajúce ikony či bubliny. Bublinu otvoríte klepnutím. Premiestnite ju presunutím."</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 6eb83ed..ed7feb9 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premakni spodaj desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Opusti oblaček"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ne prikazuj oblačkov aplikacij"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Pogovora ne prikaži v oblačku"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Klepet z oblački"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi pogovori so prikazani kot lebdeče ikone ali oblački. Če želite odpreti oblaček, se ga dotaknite. Če ga želite premakniti, ga povlecite."</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index e804c52..0b64d5d 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Lëvize poshtë djathtas"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Cilësimet e <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Hiqe flluskën"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Mos shfaq flluska"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Mos e vendos bisedën në flluskë"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bisedo duke përdorur flluskat"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Bisedat e reja shfaqen si ikona pluskuese ose flluska. Trokit për të hapur flluskën. Zvarrit për ta zhvendosur."</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 9aafa87..8f44eeb 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести доле десно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Одбаци облачић"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Без облачића"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не користи облачиће за конверзацију"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Ћаскајте у облачићима"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 6316d52..1bd744a 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Flytta längst ned till höger"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Inställningar för <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Stäng bubbla"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Visa inte bubblor"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Visa inte konversationen i bubblor"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatta med bubblor"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nya konversationer visas som flytande ikoner, så kallade bubblor. Tryck på bubblan om du vill öppna den. Dra den om du vill flytta den."</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 46bd638..f2f3bbc 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Sogeza chini kulia"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Mipangilio ya <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ondoa kiputo"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Isifanye viputo"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Usiweke viputo kwenye mazungumzo"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Piga gumzo ukitumia viputo"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Mazungumzo mapya huonekena kama aikoni au viputo vinavyoelea. Gusa ili ufungue kiputo. Buruta ili ukisogeze."</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 512bd52..581a5ab 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"దిగవు కుడివైపునకు జరుపు"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> సెట్టింగ్లు"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"బబుల్ను విస్మరించు"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"బబుల్ను చూపడం ఆపండి"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"సంభాషణను బబుల్ చేయవద్దు"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"బబుల్స్ను ఉపయోగించి చాట్ చేయండి"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"కొత్త సంభాషణలు తేలియాడే చిహ్నాలుగా లేదా బబుల్స్ లాగా కనిపిస్తాయి. బబుల్ని తెరవడానికి నొక్కండి. తరలించడానికి లాగండి."</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index e533869..44afb58 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ย้ายไปด้านขาวล่าง"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"การตั้งค่า <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ปิดบับเบิล"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"ไม่ต้องแสดงบับเบิล"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ไม่ต้องแสดงการสนทนาเป็นบับเบิล"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"แชทโดยใช้บับเบิล"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"การสนทนาใหม่ๆ จะปรากฏเป็นไอคอนแบบลอยหรือบับเบิล แตะเพื่อเปิดบับเบิล ลากเพื่อย้ายที่"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 426e83a..d287e9d 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Ilipat sa kanan sa ibaba"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Mga setting ng <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"I-dismiss ang bubble"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Huwag i-bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Huwag ipakita sa bubble ang mga pag-uusap"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Mag-chat gamit ang bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Lumalabas bilang mga nakalutang na icon o bubble ang mga bagong pag-uusap. I-tap para buksan ang bubble. I-drag para ilipat ito."</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index f4373e6..5599351 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"نیچے دائیں جانب لے جائیں"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ترتیبات"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"بلبلہ برخاست کریں"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"بلبلہ دکھانا بند کریں"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"گفتگو بلبلہ نہ کریں"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"بلبلے کے ذریعے چیٹ کریں"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"نئی گفتگوئیں فلوٹنگ آئیکن یا بلبلے کے طور پر ظاہر ہوں گی۔ بلبلہ کھولنے کے لیے تھپتھپائیں۔ اسے منتقل کرنے کے لیے گھسیٹیں۔"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 8c07814..54898156 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Quyi oʻngga surish"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> sozlamalari"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bulutchani yopish"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Qalqib chiqmasin"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Suhbatlar bulutchalar shaklida chiqmasin"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bulutchalar yordamida subhatlashish"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Yangi xabarlar qalqib chiquvchi belgilar yoki bulutchalar kabi chiqadi. Xabarni ochish uchun bildirishnoma ustiga bosing. Xabarni qayta joylash uchun bildirishnomani suring."</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index bbb3639..bb144a7 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Chuyển tới dưới cùng bên phải"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Đóng bong bóng"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Không hiện bong bóng trò chuyện"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Dừng sử dụng bong bóng cho cuộc trò chuyện"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Trò chuyện bằng bong bóng trò chuyện"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Các cuộc trò chuyện mới sẽ xuất hiện dưới dạng biểu tượng nổi hoặc bong bóng trò chuyện. Nhấn để mở bong bóng trò chuyện. Kéo để di chuyển bong bóng trò chuyện."</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index caca25a..4b2ee18 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"移至右下角"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>设置"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"关闭对话泡"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"不显示对话泡"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"不以对话泡形式显示对话"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"使用对话泡聊天"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新对话会以浮动图标或对话泡形式显示。点按即可打开对话泡。拖动即可移动对话泡。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 7787e77..1a6e46c 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -68,8 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Hambisa inkinobho ngakwesokudla"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> izilungiselelo"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Cashisa ibhamuza"</string>
- <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
- <skip />
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Ungabhamuzi"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ungayibhamuzi ingxoxo"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Xoxa usebenzisa amabhamuza"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Izingxoxo ezintsha zivela njengezithonjana ezintantayo, noma amabhamuza. Thepha ukuze uvule ibhamuza. Hudula ukuze ulihambise."</string>
diff --git a/libs/WindowManager/Shell/res/values/attrs.xml b/libs/WindowManager/Shell/res/values/attrs.xml
index 2aad4c1..fbb5caa 100644
--- a/libs/WindowManager/Shell/res/values/attrs.xml
+++ b/libs/WindowManager/Shell/res/values/attrs.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ Copyright (C) 2023 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.
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 6fb70006..4a1635d 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -45,6 +45,9 @@
<!-- Letterbox Dialog -->
<color name="letterbox_dialog_background">@android:color/system_neutral1_900</color>
+ <!-- Reachability Education color for hand icon and text-->
+ <color name="letterbox_reachability_education_item_color">#BFC8CC</color>
+
<!-- GM2 colors -->
<color name="GM2_grey_200">#E8EAED</color>
<color name="GM2_grey_700">#5F6368</color>
@@ -54,4 +57,14 @@
<color name="splash_screen_bg_light">#FFFFFF</color>
<color name="splash_screen_bg_dark">#000000</color>
<color name="splash_window_background_default">@color/splash_screen_bg_light</color>
+
+ <!-- Desktop Mode -->
+ <color name="desktop_mode_caption_handle_bar_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_handle_bar_dark">#1C1C17</color>
+ <color name="desktop_mode_caption_expand_button_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_expand_button_dark">#48473A</color>
+ <color name="desktop_mode_caption_close_button_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_close_button_dark">#1C1C17</color>
+ <color name="desktop_mode_caption_app_name_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_app_name_dark">#1C1C17</color>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 680ad51..c98a056 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -327,6 +327,15 @@
<!-- The vertical padding for the buttons in the letterbox restart dialog -->
<dimen name="letterbox_restart_dialog_vertical_padding">8dp</dimen>
+ <!-- The margin between the reachability dialog container and its parent. -->
+ <dimen name="letterbox_reachability_education_dialog_margin">16dp</dimen>
+
+ <!-- The width of each item in the reachability education -->
+ <dimen name="letterbox_reachability_education_item_width">118dp</dimen>
+
+ <!-- The size of the icon in the item of reachability education -->
+ <dimen name="letterbox_reachability_education_item_image_size">24dp</dimen>
+
<!-- The width of the brand image on staring surface. -->
<dimen name="starting_surface_brand_image_width">200dp</dimen>
@@ -365,6 +374,7 @@
<dimen name="freeform_decor_caption_menu_width">256dp</dimen>
<dimen name="freeform_decor_caption_menu_height">250dp</dimen>
+ <dimen name="freeform_decor_caption_menu_height_no_windowing_controls">210dp</dimen>
<dimen name="freeform_resize_handle">30dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 9f6cf79..2b196ca 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -221,6 +221,17 @@
<!-- Checkbox text for asking to not show the restart confirmation dialog again. [CHAR LIMIT=NONE] -->
<string name="letterbox_restart_dialog_checkbox_title">Don\u2019t show again</string>
+ <!-- When an app is letterboxed, it is initially centered on the screen but the user can
+ double tap to move the app to a different position. With a double-tap on the right,
+ the app moves the right of the screen and with a double-tap on the left the app moves
+ on the left. The same happens if the app has space to be moved to the top or bottom of
+ the screen. This time the double-tap can happen on the top or bottom of the screen.
+ To teach the user about this feature, we display an education explaining how the double-tap
+ works and how the app can be moved on the screen.
+ This is the text we show to the user below an animated icon visualizing the double-tap
+ action. [CHAR LIMIT=NONE] -->
+ <string name="letterbox_reachability_reposition_text">Double-tap to move this app</string>
+
<!-- Freeform window caption strings -->
<!-- Accessibility text for the maximize window button [CHAR LIMIT=NONE] -->
<string name="maximize_button_text">Maximize</string>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index bc2e71d..d0782ad 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -144,4 +144,20 @@
@*android:string/config_bodyFontFamily
</item>
</style>
+
+ <style name="ReachabilityEduHandLayout" parent="Theme.AppCompat">
+ <item name="android:focusable">false</item>
+ <item name="android:focusableInTouchMode">false</item>
+ <item name="android:background">@android:color/transparent</item>
+ <item name="android:contentDescription">@string/restart_button_description</item>
+ <item name="android:visibility">invisible</item>
+ <item name="android:lineSpacingExtra">-1sp</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:textAlignment">center</item>
+ <item name="android:textColor">@color/letterbox_reachability_education_item_color</item>
+ <item name="android:textAppearance">
+ @*android:style/TextAppearance.DeviceDefault.Body2
+ </item>
+ </style>
+
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 1df6ecd..1e3d795 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -224,7 +224,7 @@
openingWholeScreenBounds.union(change.getEndAbsBounds());
} else {
closingChanges.add(change);
- closingWholeScreenBounds.union(change.getEndAbsBounds());
+ closingWholeScreenBounds.union(change.getStartAbsBounds());
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
index cb1a6e7..ac6e4c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
@@ -59,7 +59,7 @@
*/
private static final boolean ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
SystemProperties.getBoolean(
- "persist.wm.debug.enable_move_floating_window_in_tabletop", false);
+ "persist.wm.debug.enable_move_floating_window_in_tabletop", true);
/**
* Prefer the {@link #PREFERRED_TABLETOP_HALF_TOP} if this flag is enabled,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index b447a54..5459094 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -738,6 +738,10 @@
getRefBounds2(mTempRect);
t.setPosition(leash2, mTempRect.left, mTempRect.top)
.setWindowCrop(leash2, mTempRect.width(), mTempRect.height());
+ // Make right or bottom side surface always higher than left or top side to avoid weird
+ // animation when dismiss split. e.g. App surface fling above on decor surface.
+ t.setLayer(leash1, 1);
+ t.setLayer(leash2, 2);
if (mImePositionProcessor.adjustSurfaceLayoutForIme(
t, dividerLeash, leash1, leash2, dimLayer1, dimLayer2)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
index 06f0a70..902c41c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java
@@ -39,22 +39,41 @@
"enable_letterbox_restart_confirmation_dialog";
private static final String KEY_ENABLE_LETTERBOX_REACHABILITY_EDUCATION =
- "enable_letterbox_reachability_education";
+ "enable_letterbox_education_for_reachability";
private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_RESTART_DIALOG = true;
- private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_REACHABILITY_EDUCATION = false;
+ private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_REACHABILITY_EDUCATION = true;
/**
- * The name of the {@link SharedPreferences} that holds which user has seen the Restart
- * confirmation dialog.
+ * The name of the {@link SharedPreferences} that holds information about compat ui.
*/
- private static final String DONT_SHOW_RESTART_DIALOG_PREF_NAME = "dont_show_restart_dialog";
+ private static final String COMPAT_UI_SHARED_PREFERENCES = "dont_show_restart_dialog";
/**
- * The {@link SharedPreferences} instance for {@link #DONT_SHOW_RESTART_DIALOG_PREF_NAME}.
+ * The name of the {@link SharedPreferences} that holds which user has seen the Letterbox
+ * Education dialog.
*/
- private final SharedPreferences mSharedPreferences;
+ private static final String HAS_SEEN_LETTERBOX_EDUCATION_SHARED_PREFERENCES =
+ "has_seen_letterbox_education";
+
+ /**
+ * Key prefix for the {@link SharedPreferences} entries related to the reachability
+ * education.
+ */
+ private static final String HAS_SEEN_REACHABILITY_EDUCATION_KEY_PREFIX =
+ "has_seen_reachability_education";
+
+ /**
+ * The {@link SharedPreferences} instance for the restart dialog and the reachability
+ * education.
+ */
+ private final SharedPreferences mCompatUISharedPreferences;
+
+ /**
+ * The {@link SharedPreferences} instance for the letterbox education dialog.
+ */
+ private final SharedPreferences mLetterboxEduSharedPreferences;
// Whether the extended restart dialog is enabled
private boolean mIsRestartDialogEnabled;
@@ -88,8 +107,10 @@
DEFAULT_VALUE_ENABLE_LETTERBOX_REACHABILITY_EDUCATION);
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_COMPAT, mainExecutor,
this);
- mSharedPreferences = context.getSharedPreferences(DONT_SHOW_RESTART_DIALOG_PREF_NAME,
+ mCompatUISharedPreferences = context.getSharedPreferences(getCompatUISharedPreferenceName(),
Context.MODE_PRIVATE);
+ mLetterboxEduSharedPreferences = context.getSharedPreferences(
+ getHasSeenLetterboxEducationSharedPreferencedName(), Context.MODE_PRIVATE);
}
/**
@@ -122,20 +143,53 @@
mIsReachabilityEducationOverrideEnabled = enabled;
}
- boolean getDontShowRestartDialogAgain(TaskInfo taskInfo) {
- final int userId = taskInfo.userId;
- final String packageName = taskInfo.topActivity.getPackageName();
- return mSharedPreferences.getBoolean(
- getDontShowAgainRestartKey(userId, packageName), /* default= */ false);
- }
-
void setDontShowRestartDialogAgain(TaskInfo taskInfo) {
- final int userId = taskInfo.userId;
- final String packageName = taskInfo.topActivity.getPackageName();
- mSharedPreferences.edit().putBoolean(getDontShowAgainRestartKey(userId, packageName),
+ mCompatUISharedPreferences.edit().putBoolean(
+ getDontShowAgainRestartKey(taskInfo.userId, taskInfo.topActivity.getPackageName()),
true).apply();
}
+ boolean shouldShowRestartDialogAgain(TaskInfo taskInfo) {
+ return !mCompatUISharedPreferences.getBoolean(getDontShowAgainRestartKey(taskInfo.userId,
+ taskInfo.topActivity.getPackageName()), /* default= */ false);
+ }
+
+ void setDontShowReachabilityEducationAgain(TaskInfo taskInfo) {
+ mCompatUISharedPreferences.edit().putBoolean(
+ getDontShowAgainReachabilityEduKey(taskInfo.userId,
+ taskInfo.topActivity.getPackageName()), true).apply();
+ }
+
+ boolean shouldShowReachabilityEducation(@NonNull TaskInfo taskInfo) {
+ return getHasSeenLetterboxEducation(taskInfo.userId)
+ && !mCompatUISharedPreferences.getBoolean(
+ getDontShowAgainReachabilityEduKey(taskInfo.userId,
+ taskInfo.topActivity.getPackageName()), /* default= */false);
+ }
+
+ boolean getHasSeenLetterboxEducation(int userId) {
+ return mLetterboxEduSharedPreferences
+ .getBoolean(getDontShowLetterboxEduKey(userId), /* default= */ false);
+ }
+
+ void setSeenLetterboxEducation(int userId) {
+ mLetterboxEduSharedPreferences.edit().putBoolean(getDontShowLetterboxEduKey(userId),
+ true).apply();
+ }
+
+ protected String getCompatUISharedPreferenceName() {
+ return COMPAT_UI_SHARED_PREFERENCES;
+ }
+
+ protected String getHasSeenLetterboxEducationSharedPreferencedName() {
+ return HAS_SEEN_LETTERBOX_EDUCATION_SHARED_PREFERENCES;
+ }
+
+ /**
+ * Updates the {@link DeviceConfig} state for the CompatUI
+ * @param properties Contains the complete collection of properties which have changed for a
+ * single namespace. This includes only those which were added, updated,
+ */
@Override
public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
if (properties.getKeyset().contains(KEY_ENABLE_LETTERBOX_RESTART_DIALOG)) {
@@ -152,6 +206,14 @@
}
}
+ private static String getDontShowAgainReachabilityEduKey(int userId, String packageName) {
+ return HAS_SEEN_REACHABILITY_EDUCATION_KEY_PREFIX + "_" + packageName + "@" + userId;
+ }
+
+ private static String getDontShowLetterboxEduKey(int userId) {
+ return String.valueOf(userId);
+ }
+
private String getDontShowAgainRestartKey(int userId, String packageName) {
return packageName + "@" + userId;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 6950f24..4d83247 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -112,6 +112,12 @@
@Nullable
private LetterboxEduWindowManager mActiveLetterboxEduLayout;
+ /**
+ * The active Reachability UI layout.
+ */
+ @Nullable
+ private ReachabilityEduWindowManager mActiveReachabilityEduLayout;
+
/** Avoid creating display context frequently for non-default display. */
private final SparseArray<WeakReference<Context>> mDisplayContextCache = new SparseArray<>(0);
@@ -195,6 +201,7 @@
createOrUpdateCompatLayout(taskInfo, taskListener);
createOrUpdateLetterboxEduLayout(taskInfo, taskListener);
createOrUpdateRestartDialogLayout(taskInfo, taskListener);
+ createOrUpdateReachabilityEduLayout(taskInfo, taskListener, false);
}
@Override
@@ -308,7 +315,7 @@
private void onRestartButtonClicked(
Pair<TaskInfo, ShellTaskOrganizer.TaskListener> taskInfoState) {
if (mCompatUIConfiguration.isRestartDialogEnabled()
- && !mCompatUIConfiguration.getDontShowRestartDialogAgain(
+ && mCompatUIConfiguration.shouldShowRestartDialogAgain(
taskInfoState.first)) {
// We need to show the dialog
mSetOfTaskIdsShowingRestartDialog.add(taskInfoState.first.taskId);
@@ -355,13 +362,15 @@
ShellTaskOrganizer.TaskListener taskListener) {
return new LetterboxEduWindowManager(context, taskInfo,
mSyncQueue, taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId),
- mTransitionsLazy.get(),
- this::onLetterboxEduDismissed,
- mDockStateReader);
+ mTransitionsLazy.get(), this::onLetterboxEduDismissed, mDockStateReader,
+ mCompatUIConfiguration);
}
- private void onLetterboxEduDismissed() {
+ private void onLetterboxEduDismissed(
+ Pair<TaskInfo, ShellTaskOrganizer.TaskListener> stateInfo) {
mActiveLetterboxEduLayout = null;
+ // We need to update the UI
+ createOrUpdateReachabilityEduLayout(stateInfo.first, stateInfo.second, true);
}
private void createOrUpdateRestartDialogLayout(TaskInfo taskInfo,
@@ -419,6 +428,47 @@
onCompatInfoChanged(stateInfo.first, stateInfo.second);
}
+ private void createOrUpdateReachabilityEduLayout(TaskInfo taskInfo,
+ ShellTaskOrganizer.TaskListener taskListener, boolean forceUpdate) {
+ if (mActiveReachabilityEduLayout != null) {
+ mActiveReachabilityEduLayout.forceUpdate(forceUpdate);
+ // UI already exists, update the UI layout.
+ if (!mActiveReachabilityEduLayout.updateCompatInfo(taskInfo, taskListener,
+ showOnDisplay(mActiveReachabilityEduLayout.getDisplayId()))) {
+ // The layout is no longer eligible to be shown, remove from active layouts.
+ mActiveReachabilityEduLayout = null;
+ }
+ return;
+ }
+ // Create a new UI layout.
+ final Context context = getOrCreateDisplayContext(taskInfo.displayId);
+ if (context == null) {
+ return;
+ }
+ ReachabilityEduWindowManager newLayout = createReachabilityEduWindowManager(context,
+ taskInfo, taskListener);
+ if (newLayout.createLayout(showOnDisplay(taskInfo.displayId))) {
+ // The new layout is eligible to be shown, make it the active layout.
+ if (mActiveReachabilityEduLayout != null) {
+ // Release the previous layout since at most one can be active.
+ // Since letterbox reachability education is only shown once to the user,
+ // releasing the previous layout is only a precaution.
+ mActiveReachabilityEduLayout.release();
+ }
+ mActiveReachabilityEduLayout = newLayout;
+ }
+ }
+
+ @VisibleForTesting
+ ReachabilityEduWindowManager createReachabilityEduWindowManager(Context context,
+ TaskInfo taskInfo,
+ ShellTaskOrganizer.TaskListener taskListener) {
+ return new ReachabilityEduWindowManager(context, taskInfo, mSyncQueue, mCallback,
+ taskListener, mDisplayController.getDisplayLayout(taskInfo.displayId),
+ mCompatUIConfiguration, mMainExecutor);
+ }
+
+
private void removeLayouts(int taskId) {
final CompatUIWindowManager layout = mActiveCompatLayouts.get(taskId);
if (layout != null) {
@@ -438,6 +488,11 @@
mTaskIdToRestartDialogWindowManagerMap.remove(taskId);
mSetOfTaskIdsShowingRestartDialog.remove(taskId);
}
+ if (mActiveReachabilityEduLayout != null
+ && mActiveReachabilityEduLayout.getTaskId() == taskId) {
+ mActiveReachabilityEduLayout.release();
+ mActiveReachabilityEduLayout = null;
+ }
}
private Context getOrCreateDisplayContext(int displayId) {
@@ -490,6 +545,9 @@
callback.accept(layout);
}
}
+ if (mActiveReachabilityEduLayout != null && condition.test(mActiveReachabilityEduLayout)) {
+ callback.accept(mActiveReachabilityEduLayout);
+ }
}
/** An implementation of {@link OnInsetsChangedListener} for a given display id. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
index b22c9c7..9c4e79c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManagerAbstract.java
@@ -384,7 +384,7 @@
// Cannot be wrap_content as this determines the actual window size
width, height,
TYPE_APPLICATION_OVERLAY,
- FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL,
+ getWindowManagerLayoutParamsFlags(),
PixelFormat.TRANSLUCENT);
winParams.token = new Binder();
winParams.setTitle(getClass().getSimpleName() + mTaskId);
@@ -392,6 +392,13 @@
return winParams;
}
+ /**
+ * @return Flags to use for the {@link WindowManager} layout
+ */
+ protected int getWindowManagerLayoutParamsFlags() {
+ return FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL;
+ }
+
protected final String getTag() {
return getClass().getSimpleName();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
index bfdbfe3..0c21c8c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
@@ -18,12 +18,13 @@
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
-import android.content.SharedPreferences;
import android.graphics.Rect;
import android.provider.Settings;
+import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
@@ -38,10 +39,12 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.transition.Transitions;
+import java.util.function.Consumer;
+
/**
* Window manager for the Letterbox Education.
*/
-public class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
+class LetterboxEduWindowManager extends CompatUIWindowManagerAbstract {
/**
* The Letterbox Education should be the topmost child of the Task in case there can be more
@@ -49,19 +52,6 @@
*/
public static final int Z_ORDER = Integer.MAX_VALUE;
- /**
- * The name of the {@link SharedPreferences} that holds which user has seen the Letterbox
- * Education dialog.
- */
- @VisibleForTesting
- static final String HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME =
- "has_seen_letterbox_education";
-
- /**
- * The {@link SharedPreferences} instance for {@link #HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME}.
- */
- private final SharedPreferences mSharedPreferences;
-
private final DialogAnimationController<LetterboxEduDialogLayout> mAnimationController;
private final Transitions mTransitions;
@@ -73,6 +63,10 @@
*/
private final int mUserId;
+ private final Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnDismissCallback;
+
+ private final CompatUIConfiguration mCompatUIConfiguration;
+
// Remember the last reported state in case visibility changes due to keyguard or IME updates.
private boolean mEligibleForLetterboxEducation;
@@ -80,7 +74,8 @@
@VisibleForTesting
LetterboxEduDialogLayout mLayout;
- private final Runnable mOnDismissCallback;
+ @NonNull
+ private TaskInfo mTaskInfo;
/**
* The vertical margin between the dialog container and the task stable bounds (excluding
@@ -90,33 +85,35 @@
private final DockStateReader mDockStateReader;
- public LetterboxEduWindowManager(Context context, TaskInfo taskInfo,
+ LetterboxEduWindowManager(Context context, TaskInfo taskInfo,
SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener,
DisplayLayout displayLayout, Transitions transitions,
- Runnable onDismissCallback, DockStateReader dockStateReader) {
+ Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onDismissCallback,
+ DockStateReader dockStateReader, CompatUIConfiguration compatUIConfiguration) {
this(context, taskInfo, syncQueue, taskListener, displayLayout, transitions,
onDismissCallback,
new DialogAnimationController<>(context, /* tag */ "LetterboxEduWindowManager"),
- dockStateReader);
+ dockStateReader, compatUIConfiguration);
}
@VisibleForTesting
LetterboxEduWindowManager(Context context, TaskInfo taskInfo,
SyncTransactionQueue syncQueue, ShellTaskOrganizer.TaskListener taskListener,
- DisplayLayout displayLayout, Transitions transitions, Runnable onDismissCallback,
+ DisplayLayout displayLayout, Transitions transitions,
+ Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onDismissCallback,
DialogAnimationController<LetterboxEduDialogLayout> animationController,
- DockStateReader dockStateReader) {
+ DockStateReader dockStateReader, CompatUIConfiguration compatUIConfiguration) {
super(context, taskInfo, syncQueue, taskListener, displayLayout);
+ mTaskInfo = taskInfo;
mTransitions = transitions;
mOnDismissCallback = onDismissCallback;
mAnimationController = animationController;
mUserId = taskInfo.userId;
- mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
- mSharedPreferences = mContext.getSharedPreferences(HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
- Context.MODE_PRIVATE);
mDialogVerticalMargin = (int) mContext.getResources().getDimension(
R.dimen.letterbox_education_dialog_margin);
mDockStateReader = dockStateReader;
+ mCompatUIConfiguration = compatUIConfiguration;
+ mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
}
@Override
@@ -142,8 +139,8 @@
// the controller will create a new instance of this class since this one isn't eligible).
// - If the layout isn't null then it was previously showing, and we shouldn't check if the
// user has seen the letterbox education before.
- return mEligibleForLetterboxEducation && !isTaskbarEduShowing()
- && (mLayout != null || !getHasSeenLetterboxEducation())
+ return mEligibleForLetterboxEducation && !isTaskbarEduShowing() && (mLayout != null
+ || !mCompatUIConfiguration.getHasSeenLetterboxEducation(mUserId))
&& !mDockStateReader.isDocked();
}
@@ -192,7 +189,6 @@
// Dialog has already been released.
return;
}
- setSeenLetterboxEducation();
mLayout.setDismissOnClickListener(this::onDismiss);
// Focus on the dialog title for accessibility.
mLayout.getDialogTitle().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
@@ -202,10 +198,11 @@
if (mLayout == null) {
return;
}
+ mCompatUIConfiguration.setSeenLetterboxEducation(mUserId);
mLayout.setDismissOnClickListener(null);
mAnimationController.startExitAnimation(mLayout, () -> {
release();
- mOnDismissCallback.run();
+ mOnDismissCallback.accept(Pair.create(mTaskInfo, getTaskListener()));
});
}
@@ -218,6 +215,7 @@
@Override
public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
boolean canShow) {
+ mTaskInfo = taskInfo;
mEligibleForLetterboxEducation = taskInfo.topActivityEligibleForLetterboxEducation;
return super.updateCompatInfo(taskInfo, taskListener, canShow);
@@ -248,18 +246,6 @@
taskBounds.height());
}
- private boolean getHasSeenLetterboxEducation() {
- return mSharedPreferences.getBoolean(getPrefKey(), /* default= */ false);
- }
-
- private void setSeenLetterboxEducation() {
- mSharedPreferences.edit().putBoolean(getPrefKey(), true).apply();
- }
-
- private String getPrefKey() {
- return String.valueOf(mUserId);
- }
-
@VisibleForTesting
boolean isTaskbarEduShowing() {
return Settings.Secure.getInt(mContext.getContentResolver(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduHandLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduHandLayout.java
new file mode 100644
index 0000000..6081ef1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduHandLayout.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import android.content.Context;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.appcompat.widget.AppCompatTextView;
+
+/**
+ * Custom layout for Reachability Education hand.
+ */
+public class ReachabilityEduHandLayout extends AppCompatTextView {
+
+ private Drawable mHandDrawable;
+
+ public ReachabilityEduHandLayout(Context context) {
+ this(context, null);
+ }
+
+ public ReachabilityEduHandLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ReachabilityEduHandLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mHandDrawable = getCompoundDrawables()[/* top */ 1];
+ }
+
+ void hide() {
+ stopAnimation();
+ setAlpha(0);
+ setVisibility(View.INVISIBLE);
+ }
+
+ void startAnimation() {
+ if (mHandDrawable instanceof Animatable) {
+ final Animatable animatedBg = (Animatable) mHandDrawable;
+ animatedBg.start();
+ }
+ }
+
+ void stopAnimation() {
+ if (mHandDrawable instanceof Animatable) {
+ final Animatable animatedBg = (Animatable) mHandDrawable;
+ animatedBg.stop();
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduLayout.java
new file mode 100644
index 0000000..6a72d28
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduLayout.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.app.TaskInfo;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.widget.FrameLayout;
+
+import com.android.wm.shell.R;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+/**
+ * Container for reachability education which handles all the show/hide animations.
+ */
+public class ReachabilityEduLayout extends FrameLayout {
+
+ private static final float ALPHA_FULL_TRANSPARENT = 0f;
+
+ private static final float ALPHA_FULL_OPAQUE = 1f;
+
+ private static final long VISIBILITY_SHOW_ANIMATION_DURATION_MS = 167;
+
+ private static final long VISIBILITY_SHOW_ANIMATION_DELAY_MS = 250;
+
+ private static final long VISIBILITY_SHOW_DOUBLE_TAP_ANIMATION_DELAY_MS = 80;
+
+ private static final long MARGINS_ANIMATION_DURATION_MS = 250;
+
+ private ReachabilityEduWindowManager mWindowManager;
+
+ private ReachabilityEduHandLayout mMoveLeftButton;
+ private ReachabilityEduHandLayout mMoveRightButton;
+ private ReachabilityEduHandLayout mMoveUpButton;
+ private ReachabilityEduHandLayout mMoveDownButton;
+
+ private int mLastLeftMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ private int mLastRightMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ private int mLastTopMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ private int mLastBottomMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+
+ private boolean mIsLayoutActive;
+
+ public ReachabilityEduLayout(Context context) {
+ this(context, null);
+ }
+
+ public ReachabilityEduLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ReachabilityEduLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public ReachabilityEduLayout(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ void inject(ReachabilityEduWindowManager windowManager) {
+ mWindowManager = windowManager;
+ }
+
+ void handleVisibility(boolean isActivityLetterboxed, int letterboxVerticalPosition,
+ int letterboxHorizontalPosition, int availableWidth, int availableHeight,
+ boolean isDoubleTap) {
+ // If the app is not letterboxed we hide all the buttons.
+ if (!mIsLayoutActive || !isActivityLetterboxed || (
+ letterboxHorizontalPosition == TaskInfo.PROPERTY_VALUE_UNSET
+ && letterboxVerticalPosition == TaskInfo.PROPERTY_VALUE_UNSET)) {
+ hideAllImmediately();
+ } else if (letterboxHorizontalPosition != TaskInfo.PROPERTY_VALUE_UNSET) {
+ handleLetterboxHorizontalPosition(availableWidth, letterboxHorizontalPosition,
+ isDoubleTap);
+ } else {
+ handleLetterboxVerticalPosition(availableHeight, letterboxVerticalPosition,
+ isDoubleTap);
+ }
+ }
+
+ void hideAllImmediately() {
+ mMoveLeftButton.hide();
+ mMoveRightButton.hide();
+ mMoveUpButton.hide();
+ mMoveDownButton.hide();
+ mLastLeftMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ mLastRightMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ mLastTopMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ mLastBottomMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ }
+
+ void setIsLayoutActive(boolean isLayoutActive) {
+ this.mIsLayoutActive = isLayoutActive;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mMoveLeftButton = findViewById(R.id.reachability_move_left_button);
+ mMoveRightButton = findViewById(R.id.reachability_move_right_button);
+ mMoveUpButton = findViewById(R.id.reachability_move_up_button);
+ mMoveDownButton = findViewById(R.id.reachability_move_down_button);
+ mMoveLeftButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ mMoveRightButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ mMoveUpButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ mMoveDownButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ }
+
+ private Animator marginAnimator(View view, Function<LayoutParams, Integer> marginSupplier,
+ BiConsumer<LayoutParams, Integer> marginConsumer, int from, int to) {
+ final LayoutParams layoutParams = ((LayoutParams) view.getLayoutParams());
+ ValueAnimator animator = ValueAnimator.ofInt(marginSupplier.apply(layoutParams), from, to);
+ animator.addUpdateListener(valueAnimator -> {
+ marginConsumer.accept(layoutParams, (Integer) valueAnimator.getAnimatedValue());
+ view.requestLayout();
+ });
+ animator.setDuration(MARGINS_ANIMATION_DURATION_MS);
+ return animator;
+ }
+
+ private void handleLetterboxHorizontalPosition(int availableWidth,
+ int letterboxHorizontalPosition, boolean isDoubleTap) {
+ mMoveUpButton.hide();
+ mMoveDownButton.hide();
+ mLastTopMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ mLastBottomMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ // We calculate the available space on the left and right
+ final int horizontalGap = availableWidth / 2;
+ final int leftAvailableSpace = letterboxHorizontalPosition * horizontalGap;
+ final int rightAvailableSpace = availableWidth - leftAvailableSpace;
+ // We show the button if we have enough space
+ if (leftAvailableSpace >= mMoveLeftButton.getMeasuredWidth()) {
+ int newLeftMargin = (horizontalGap - mMoveLeftButton.getMeasuredWidth()) / 2;
+ if (mLastLeftMargin == TaskInfo.PROPERTY_VALUE_UNSET) {
+ mLastLeftMargin = newLeftMargin;
+ }
+ if (mLastLeftMargin != newLeftMargin) {
+ marginAnimator(mMoveLeftButton, layoutParams -> layoutParams.leftMargin,
+ (layoutParams, margin) -> layoutParams.leftMargin = margin,
+ mLastLeftMargin, newLeftMargin).start();
+ } else {
+ final LayoutParams leftParams = ((LayoutParams) mMoveLeftButton.getLayoutParams());
+ leftParams.leftMargin = mLastLeftMargin;
+ mMoveLeftButton.setLayoutParams(leftParams);
+ }
+ showItem(mMoveLeftButton, isDoubleTap);
+ } else {
+ mMoveLeftButton.hide();
+ mLastLeftMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ }
+ if (rightAvailableSpace >= mMoveRightButton.getMeasuredWidth()) {
+ int newRightMargin = (horizontalGap - mMoveRightButton.getMeasuredWidth()) / 2;
+ if (mLastRightMargin == TaskInfo.PROPERTY_VALUE_UNSET) {
+ mLastRightMargin = newRightMargin;
+ }
+ if (mLastRightMargin != newRightMargin) {
+ marginAnimator(mMoveRightButton, layoutParams -> layoutParams.rightMargin,
+ (layoutParams, margin) -> layoutParams.rightMargin = margin,
+ mLastRightMargin, newRightMargin).start();
+ } else {
+ final LayoutParams rightParams =
+ ((LayoutParams) mMoveRightButton.getLayoutParams());
+ rightParams.rightMargin = mLastRightMargin;
+ mMoveRightButton.setLayoutParams(rightParams);
+ }
+ showItem(mMoveRightButton, isDoubleTap);
+ } else {
+ mMoveRightButton.hide();
+ mLastRightMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ }
+ }
+
+ private void handleLetterboxVerticalPosition(int availableHeight,
+ int letterboxVerticalPosition, boolean isDoubleTap) {
+ mMoveLeftButton.hide();
+ mMoveRightButton.hide();
+ mLastLeftMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ mLastRightMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ // We calculate the available space on the left and right
+ final int verticalGap = availableHeight / 2;
+ final int topAvailableSpace = letterboxVerticalPosition * verticalGap;
+ final int bottomAvailableSpace = availableHeight - topAvailableSpace;
+ if (topAvailableSpace >= mMoveUpButton.getMeasuredHeight()) {
+ int newTopMargin = (verticalGap - mMoveUpButton.getMeasuredHeight()) / 2;
+ if (mLastTopMargin == TaskInfo.PROPERTY_VALUE_UNSET) {
+ mLastTopMargin = newTopMargin;
+ }
+ if (mLastTopMargin != newTopMargin) {
+ marginAnimator(mMoveUpButton, layoutParams -> layoutParams.topMargin,
+ (layoutParams, margin) -> layoutParams.topMargin = margin,
+ mLastTopMargin, newTopMargin).start();
+ } else {
+ final LayoutParams topParams = ((LayoutParams) mMoveUpButton.getLayoutParams());
+ topParams.topMargin = mLastTopMargin;
+ mMoveUpButton.setLayoutParams(topParams);
+ }
+ showItem(mMoveUpButton, isDoubleTap);
+ } else {
+ mMoveUpButton.hide();
+ mLastTopMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ }
+ if (bottomAvailableSpace >= mMoveDownButton.getMeasuredHeight()) {
+ int newBottomMargin = (verticalGap - mMoveDownButton.getMeasuredHeight()) / 2;
+ if (mLastBottomMargin == TaskInfo.PROPERTY_VALUE_UNSET) {
+ mLastBottomMargin = newBottomMargin;
+ }
+ if (mLastBottomMargin != newBottomMargin) {
+ marginAnimator(mMoveDownButton, layoutParams -> layoutParams.bottomMargin,
+ (layoutParams, margin) -> layoutParams.bottomMargin = margin,
+ mLastBottomMargin, newBottomMargin).start();
+ } else {
+ final LayoutParams bottomParams =
+ ((LayoutParams) mMoveDownButton.getLayoutParams());
+ bottomParams.bottomMargin = mLastBottomMargin;
+ mMoveDownButton.setLayoutParams(bottomParams);
+ }
+ showItem(mMoveDownButton, isDoubleTap);
+ } else {
+ mMoveDownButton.hide();
+ mLastBottomMargin = TaskInfo.PROPERTY_VALUE_UNSET;
+ }
+ }
+
+ private void showItem(ReachabilityEduHandLayout view, boolean fromDoubleTap) {
+ if (view.getVisibility() == View.VISIBLE) {
+ // Already visible we just start animation
+ view.startAnimation();
+ return;
+ }
+ view.setVisibility(View.VISIBLE);
+ final long delay = fromDoubleTap ? VISIBILITY_SHOW_DOUBLE_TAP_ANIMATION_DELAY_MS
+ : VISIBILITY_SHOW_ANIMATION_DELAY_MS;
+ AlphaAnimation alphaAnimation = new AlphaAnimation(ALPHA_FULL_TRANSPARENT,
+ ALPHA_FULL_OPAQUE);
+ alphaAnimation.setDuration(VISIBILITY_SHOW_ANIMATION_DURATION_MS);
+ alphaAnimation.setStartOffset(delay);
+ alphaAnimation.setFillAfter(true);
+ alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ // We trigger the hand animation
+ view.setAlpha(ALPHA_FULL_OPAQUE);
+ view.startAnimation();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+ });
+ view.startAnimation(alphaAnimation);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
new file mode 100644
index 0000000..6223efa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/ReachabilityEduWindowManager.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.TaskInfo;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.CompatUIController.CompatUICallback;
+
+/**
+ * Window manager for the reachability education
+ */
+class ReachabilityEduWindowManager extends CompatUIWindowManagerAbstract {
+
+ /**
+ * The Compat UI should be below the Letterbox Education.
+ */
+ private static final int Z_ORDER = LetterboxEduWindowManager.Z_ORDER - 1;
+
+ // The time to wait before hiding the education
+ private static final long DISAPPEAR_DELAY_MS = 4000L;
+
+ private final CompatUICallback mCallback;
+
+ private final CompatUIConfiguration mCompatUIConfiguration;
+
+ private final ShellExecutor mMainExecutor;
+
+ @NonNull
+ private TaskInfo mTaskInfo;
+
+ private boolean mIsActivityLetterboxed;
+
+ private int mLetterboxVerticalPosition;
+
+ private int mLetterboxHorizontalPosition;
+
+ private int mTopActivityLetterboxWidth;
+
+ private int mTopActivityLetterboxHeight;
+
+ private long mNextHideTime = -1L;
+
+ private boolean mForceUpdate = false;
+
+ // We decided to force the visualization of the double-tap animated icons every time the user
+ // double-taps. We detect a double-tap checking the previous and current state of
+ // mLetterboxVerticalPosition and mLetterboxHorizontalPosition saving the result in this
+ // variable.
+ private boolean mHasUserDoubleTapped;
+
+ // When the size of the letterboxed app changes and the icons are visible
+ // we need to animate them.
+ private boolean mHasLetterboxSizeChanged;
+
+ @Nullable
+ @VisibleForTesting
+ ReachabilityEduLayout mLayout;
+
+ ReachabilityEduWindowManager(Context context, TaskInfo taskInfo,
+ SyncTransactionQueue syncQueue, CompatUICallback callback,
+ ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout,
+ CompatUIConfiguration compatUIConfiguration, ShellExecutor mainExecutor) {
+ super(context, taskInfo, syncQueue, taskListener, displayLayout);
+ mCallback = callback;
+ mTaskInfo = taskInfo;
+ mIsActivityLetterboxed = taskInfo.isLetterboxDoubleTapEnabled;
+ mLetterboxVerticalPosition = taskInfo.topActivityLetterboxVerticalPosition;
+ mLetterboxHorizontalPosition = taskInfo.topActivityLetterboxHorizontalPosition;
+ mTopActivityLetterboxWidth = taskInfo.topActivityLetterboxWidth;
+ mTopActivityLetterboxHeight = taskInfo.topActivityLetterboxHeight;
+ mCompatUIConfiguration = compatUIConfiguration;
+ mMainExecutor = mainExecutor;
+ }
+
+ @Override
+ protected int getZOrder() {
+ return Z_ORDER;
+ }
+
+ @Override
+ protected @Nullable View getLayout() {
+ return mLayout;
+ }
+
+ @Override
+ protected void removeLayout() {
+ mLayout = null;
+ }
+
+ @Override
+ protected boolean eligibleToShowLayout() {
+ return mCompatUIConfiguration.isReachabilityEducationEnabled()
+ && mIsActivityLetterboxed
+ && (mLetterboxVerticalPosition != -1 || mLetterboxHorizontalPosition != -1);
+ }
+
+ @Override
+ protected View createLayout() {
+ mLayout = inflateLayout();
+ mLayout.inject(this);
+
+ updateVisibilityOfViews();
+
+ return mLayout;
+ }
+
+ @VisibleForTesting
+ ReachabilityEduLayout inflateLayout() {
+ return (ReachabilityEduLayout) LayoutInflater.from(mContext).inflate(
+ R.layout.reachability_ui_layout, null);
+ }
+
+ @Override
+ public boolean updateCompatInfo(TaskInfo taskInfo, ShellTaskOrganizer.TaskListener taskListener,
+ boolean canShow) {
+ mTaskInfo = taskInfo;
+ final boolean prevIsActivityLetterboxed = mIsActivityLetterboxed;
+ final int prevLetterboxVerticalPosition = mLetterboxVerticalPosition;
+ final int prevLetterboxHorizontalPosition = mLetterboxHorizontalPosition;
+ final int prevTopActivityLetterboxWidth = mTopActivityLetterboxWidth;
+ final int prevTopActivityLetterboxHeight = mTopActivityLetterboxHeight;
+ mIsActivityLetterboxed = taskInfo.isLetterboxDoubleTapEnabled;
+ mLetterboxVerticalPosition = taskInfo.topActivityLetterboxVerticalPosition;
+ mLetterboxHorizontalPosition = taskInfo.topActivityLetterboxHorizontalPosition;
+ mTopActivityLetterboxWidth = taskInfo.topActivityLetterboxWidth;
+ mTopActivityLetterboxHeight = taskInfo.topActivityLetterboxHeight;
+
+ mHasUserDoubleTapped =
+ mLetterboxVerticalPosition != prevLetterboxVerticalPosition
+ || prevLetterboxHorizontalPosition != mLetterboxHorizontalPosition;
+ if (mHasUserDoubleTapped) {
+ // In this case we disable the reachability for the following launch of
+ // the current application. Anyway because a double tap event happened,
+ // the reachability education is displayed
+ mCompatUIConfiguration.setDontShowReachabilityEducationAgain(taskInfo);
+ }
+ if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) {
+ return false;
+ }
+
+ mHasLetterboxSizeChanged = prevTopActivityLetterboxWidth != mTopActivityLetterboxWidth
+ || prevTopActivityLetterboxHeight != mTopActivityLetterboxHeight;
+
+ if (mForceUpdate || prevIsActivityLetterboxed != mIsActivityLetterboxed
+ || prevLetterboxVerticalPosition != mLetterboxVerticalPosition
+ || prevLetterboxHorizontalPosition != mLetterboxHorizontalPosition
+ || prevTopActivityLetterboxWidth != mTopActivityLetterboxWidth
+ || prevTopActivityLetterboxHeight != mTopActivityLetterboxHeight) {
+ updateVisibilityOfViews();
+ mForceUpdate = false;
+ }
+
+ return true;
+ }
+
+ void forceUpdate(boolean forceUpdate) {
+ mForceUpdate = forceUpdate;
+ }
+
+ @Override
+ protected void onParentBoundsChanged() {
+ if (mLayout == null) {
+ return;
+ }
+ // Both the layout dimensions and dialog margins depend on the parent bounds.
+ WindowManager.LayoutParams windowLayoutParams = getWindowLayoutParams();
+ mLayout.setLayoutParams(windowLayoutParams);
+ relayout(windowLayoutParams);
+ }
+
+ /** Gets the layout params. */
+ protected WindowManager.LayoutParams getWindowLayoutParams() {
+ View layout = getLayout();
+ if (layout == null) {
+ return new WindowManager.LayoutParams();
+ }
+ // Measure how big the hint is since its size depends on the text size.
+ final Rect taskBounds = getTaskBounds();
+ layout.measure(View.MeasureSpec.makeMeasureSpec(taskBounds.width(),
+ View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(taskBounds.height(),
+ View.MeasureSpec.EXACTLY));
+ return getWindowLayoutParams(layout.getMeasuredWidth(), layout.getMeasuredHeight());
+ }
+
+ /**
+ * @return Flags to use for the WindowManager layout
+ */
+ @Override
+ protected int getWindowManagerLayoutParamsFlags() {
+ return FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE;
+ }
+
+ @Override
+ @VisibleForTesting
+ public void updateSurfacePosition() {
+ if (mLayout == null) {
+ return;
+ }
+ updateSurfacePosition(0, 0);
+ }
+
+ void updateHideTime() {
+ mNextHideTime = SystemClock.uptimeMillis() + DISAPPEAR_DELAY_MS;
+ }
+
+ private void updateVisibilityOfViews() {
+ if (mLayout == null) {
+ return;
+ }
+ if (shouldUpdateEducation()) {
+ if (!mHasLetterboxSizeChanged) {
+ mLayout.setIsLayoutActive(true);
+ }
+ int availableWidth = getTaskBounds().width() - mTopActivityLetterboxWidth;
+ int availableHeight = getTaskBounds().height() - mTopActivityLetterboxHeight;
+ mLayout.handleVisibility(mIsActivityLetterboxed, mLetterboxVerticalPosition,
+ mLetterboxHorizontalPosition, availableWidth, availableHeight,
+ mHasUserDoubleTapped);
+ if (!mHasLetterboxSizeChanged) {
+ updateHideTime();
+ mMainExecutor.executeDelayed(this::hideReachability, DISAPPEAR_DELAY_MS);
+ }
+ mHasUserDoubleTapped = false;
+ } else {
+ hideReachability();
+ }
+ }
+
+ private void hideReachability() {
+ if (mLayout != null) {
+ mLayout.setIsLayoutActive(false);
+ }
+ if (mLayout == null || !shouldHideEducation()) {
+ return;
+ }
+ mLayout.hideAllImmediately();
+ // We need this in case the icons disappear after the timeout without an explicit
+ // double tap of the user.
+ mCompatUIConfiguration.setDontShowReachabilityEducationAgain(mTaskInfo);
+ }
+
+ private boolean shouldUpdateEducation() {
+ return mForceUpdate || mHasUserDoubleTapped || mHasLetterboxSizeChanged
+ || mCompatUIConfiguration.shouldShowReachabilityEducation(mTaskInfo);
+ }
+
+ private boolean shouldHideEducation() {
+ return SystemClock.uptimeMillis() >= mNextHideTime;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
index 2440838..aab123a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/RestartDialogWindowManager.java
@@ -130,7 +130,7 @@
protected boolean eligibleToShowLayout() {
// We don't show this dialog if the user has explicitly selected so clicking on a checkbox.
return mRequestRestartDialog && !isTaskbarEduShowing() && (mLayout != null
- || !mCompatUIConfiguration.getDontShowRestartDialogAgain(mTaskInfo));
+ || mCompatUIConfiguration.shouldShowRestartDialogAgain(mTaskInfo));
}
@Override
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 3d5230d..57b5b8f 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
@@ -82,6 +82,7 @@
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.startingsurface.StartingSurface;
@@ -520,6 +521,9 @@
desktopModeTaskRepository, mainExecutor));
}
+ @BindsOptionalOf
+ abstract RecentsTransitionHandler optionalRecentsTransitionHandler();
+
//
// Shell transitions
//
@@ -803,6 +807,7 @@
Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
Optional<FreeformComponents> freeformComponents,
Optional<RecentTasksController> recentTasksOptional,
+ Optional<RecentsTransitionHandler> recentsTransitionHandlerOptional,
Optional<OneHandedController> oneHandedControllerOptional,
Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional,
Optional<ActivityEmbeddingController> activityEmbeddingOptional,
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 7a83d10..eb7c32f 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
@@ -83,6 +83,7 @@
import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -528,9 +529,20 @@
ShellInit shellInit,
Optional<SplitScreenController> splitScreenOptional,
Optional<PipTouchHandler> pipTouchHandlerOptional,
+ Optional<RecentsTransitionHandler> recentsTransitionHandler,
Transitions transitions) {
return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
- pipTouchHandlerOptional);
+ pipTouchHandlerOptional, recentsTransitionHandler);
+ }
+
+ @WMSingleton
+ @Provides
+ static RecentsTransitionHandler provideRecentsTransitionHandler(
+ ShellInit shellInit,
+ Transitions transitions,
+ Optional<RecentTasksController> recentTasksController) {
+ return new RecentsTransitionHandler(shellInit, transitions,
+ recentTasksController.orElse(null));
}
//
@@ -659,13 +671,17 @@
Context context,
ShellInit shellInit,
ShellController shellController,
+ DisplayController displayController,
ShellTaskOrganizer shellTaskOrganizer,
+ SyncTransactionQueue syncQueue,
+ RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
Transitions transitions,
@DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
@ShellMainThread ShellExecutor mainExecutor
) {
- return new DesktopTasksController(context, shellInit, shellController, shellTaskOrganizer,
- transitions, desktopModeTaskRepository, mainExecutor);
+ return new DesktopTasksController(context, shellInit, shellController, displayController,
+ shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, transitions,
+ desktopModeTaskRepository, mainExecutor);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index c9c0e40..ad334b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -41,7 +41,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArraySet;
-import android.util.Pair;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.DisplayAreaInfo;
@@ -364,10 +363,7 @@
}
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "handle shell transition request: %s", request);
- Pair<Transitions.TransitionHandler, WindowContainerTransaction> subHandler =
- mTransitions.dispatchRequest(transition, request, this);
- WindowContainerTransaction wct = subHandler != null
- ? subHandler.second : new WindowContainerTransaction();
+ WindowContainerTransaction wct = new WindowContainerTransaction();
bringDesktopAppsToFront(wct);
wct.reorder(request.getTriggerTask().token, true /* onTop */);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
new file mode 100644
index 0000000..015d5c1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.desktopmode;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.RectEvaluator;
+import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.ImageView;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * Animated visual indicator for Desktop Mode windowing transitions.
+ */
+public class DesktopModeVisualIndicator {
+
+ private final Context mContext;
+ private final DisplayController mDisplayController;
+ private final ShellTaskOrganizer mTaskOrganizer;
+ private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
+ private final ActivityManager.RunningTaskInfo mTaskInfo;
+ private final SurfaceControl mTaskSurface;
+ private SurfaceControl mLeash;
+
+ private final SyncTransactionQueue mSyncQueue;
+ private SurfaceControlViewHost mViewHost;
+
+ public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
+ ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
+ Context context, SurfaceControl taskSurface, ShellTaskOrganizer taskOrganizer,
+ RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer) {
+ mSyncQueue = syncQueue;
+ mTaskInfo = taskInfo;
+ mDisplayController = displayController;
+ mContext = context;
+ mTaskSurface = taskSurface;
+ mTaskOrganizer = taskOrganizer;
+ mRootTdaOrganizer = taskDisplayAreaOrganizer;
+ }
+
+ /**
+ * Create and animate the indicator for the exit desktop mode transition.
+ */
+ public void createFullscreenIndicator() {
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ final Resources resources = mContext.getResources();
+ final DisplayMetrics metrics = resources.getDisplayMetrics();
+ final int screenWidth = metrics.widthPixels;
+ final int screenHeight = metrics.heightPixels;
+ final int padding = mDisplayController
+ .getDisplayLayout(mTaskInfo.displayId).stableInsets().top;
+ final ImageView v = new ImageView(mContext);
+ v.setImageResource(R.drawable.desktop_windowing_transition_background);
+ final SurfaceControl.Builder builder = new SurfaceControl.Builder();
+ mRootTdaOrganizer.attachToDisplayArea(mTaskInfo.displayId, builder);
+ mLeash = builder
+ .setName("Fullscreen Indicator")
+ .setContainerLayer()
+ .build();
+ t.show(mLeash);
+ final WindowManager.LayoutParams lp =
+ new WindowManager.LayoutParams(screenWidth, screenHeight,
+ WindowManager.LayoutParams.TYPE_APPLICATION,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
+ lp.setTitle("Fullscreen indicator for Task=" + mTaskInfo.taskId);
+ lp.setTrustedOverlay();
+ final WindowlessWindowManager windowManager = new WindowlessWindowManager(
+ mTaskInfo.configuration, mLeash,
+ null /* hostInputToken */);
+ mViewHost = new SurfaceControlViewHost(mContext,
+ mDisplayController.getDisplay(mTaskInfo.displayId), windowManager,
+ "FullscreenVisualIndicator");
+ mViewHost.setView(v, lp);
+ // We want this indicator to be behind the dragged task, but in front of all others.
+ t.setRelativeLayer(mLeash, mTaskSurface, -1);
+
+ mSyncQueue.runInSync(transaction -> {
+ transaction.merge(t);
+ t.close();
+ });
+ final Rect startBounds = new Rect(padding, padding,
+ screenWidth - padding, screenHeight - padding);
+ final VisualIndicatorAnimator animator = VisualIndicatorAnimator.fullscreenIndicator(v,
+ startBounds);
+ animator.start();
+ }
+
+ /**
+ * Release the indicator and its components when it is no longer needed.
+ */
+ public void releaseFullscreenIndicator() {
+ if (mViewHost == null) return;
+ if (mViewHost != null) {
+ mViewHost.release();
+ mViewHost = null;
+ }
+
+ if (mLeash != null) {
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ t.remove(mLeash);
+ mLeash = null;
+ mSyncQueue.runInSync(transaction -> {
+ transaction.merge(t);
+ t.close();
+ });
+ }
+ }
+ /**
+ * Animator for Desktop Mode transitions which supports bounds and alpha animation.
+ */
+ private static class VisualIndicatorAnimator extends ValueAnimator {
+ private static final int FULLSCREEN_INDICATOR_DURATION = 200;
+ private static final float SCALE_ADJUSTMENT_PERCENT = 0.015f;
+ private static final float INDICATOR_FINAL_OPACITY = 0.7f;
+
+ private final ImageView mView;
+ private final Rect mStartBounds;
+ private final Rect mEndBounds;
+ private final RectEvaluator mRectEvaluator;
+
+ private VisualIndicatorAnimator(ImageView view, Rect startBounds,
+ Rect endBounds) {
+ mView = view;
+ mStartBounds = new Rect(startBounds);
+ mEndBounds = endBounds;
+ setFloatValues(0, 1);
+ mRectEvaluator = new RectEvaluator(new Rect());
+ }
+
+ /**
+ * Create animator for visual indicator of fullscreen transition
+ *
+ * @param view the view for this indicator
+ * @param startBounds the starting bounds of the fullscreen indicator
+ */
+ public static VisualIndicatorAnimator fullscreenIndicator(ImageView view,
+ Rect startBounds) {
+ view.getDrawable().setBounds(startBounds);
+ int width = startBounds.width();
+ int height = startBounds.height();
+ Rect endBounds = new Rect((int) (startBounds.left - (SCALE_ADJUSTMENT_PERCENT * width)),
+ (int) (startBounds.top - (SCALE_ADJUSTMENT_PERCENT * height)),
+ (int) (startBounds.right + (SCALE_ADJUSTMENT_PERCENT * width)),
+ (int) (startBounds.bottom + (SCALE_ADJUSTMENT_PERCENT * height)));
+ VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
+ view, startBounds, endBounds);
+ animator.setInterpolator(new DecelerateInterpolator());
+ setupFullscreenIndicatorAnimation(animator);
+ return animator;
+ }
+
+ /**
+ * Add necessary listener for animation of fullscreen indicator
+ */
+ private static void setupFullscreenIndicatorAnimation(
+ VisualIndicatorAnimator animator) {
+ animator.addUpdateListener(a -> {
+ if (animator.mView != null) {
+ animator.updateBounds(a.getAnimatedFraction(), animator.mView);
+ animator.updateIndicatorAlpha(a.getAnimatedFraction(), animator.mView);
+ } else {
+ animator.cancel();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ animator.mView.getDrawable().setBounds(animator.mEndBounds);
+ }
+ });
+ animator.setDuration(FULLSCREEN_INDICATOR_DURATION);
+ }
+
+ /**
+ * Update bounds of view based on current animation fraction.
+ * Use of delta is to animate bounds independently, in case we need to
+ * run multiple animations simultaneously.
+ *
+ * @param fraction fraction to use, compared against previous fraction
+ * @param view the view to update
+ */
+ private void updateBounds(float fraction, ImageView view) {
+ Rect currentBounds = mRectEvaluator.evaluate(fraction, mStartBounds, mEndBounds);
+ view.getDrawable().setBounds(currentBounds);
+ }
+
+ /**
+ * Fade in the fullscreen indicator
+ *
+ * @param fraction current animation fraction
+ */
+ private void updateIndicatorAlpha(float fraction, View view) {
+ view.setAlpha(fraction * INDICATOR_FINAL_OPACITY);
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 31c5e33..5696dfc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.desktopmode
import android.app.ActivityManager
+import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -37,11 +38,14 @@
import android.window.WindowContainerTransaction
import androidx.annotation.BinderThread
import com.android.internal.protolog.common.ProtoLog
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.ExecutorUtils
import com.android.wm.shell.common.ExternalInterfaceBinder
import com.android.wm.shell.common.RemoteCallable
import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.annotations.ExternalThread
import com.android.wm.shell.common.annotations.ShellMainThread
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
@@ -55,16 +59,20 @@
/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
- private val context: Context,
- shellInit: ShellInit,
- private val shellController: ShellController,
- private val shellTaskOrganizer: ShellTaskOrganizer,
- private val transitions: Transitions,
- private val desktopModeTaskRepository: DesktopModeTaskRepository,
- @ShellMainThread private val mainExecutor: ShellExecutor
+ private val context: Context,
+ shellInit: ShellInit,
+ private val shellController: ShellController,
+ private val displayController: DisplayController,
+ private val shellTaskOrganizer: ShellTaskOrganizer,
+ private val syncQueue: SyncTransactionQueue,
+ private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
+ private val transitions: Transitions,
+ private val desktopModeTaskRepository: DesktopModeTaskRepository,
+ @ShellMainThread private val mainExecutor: ShellExecutor
) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler {
private val desktopMode: DesktopModeImpl
+ private var visualIndicator: DesktopModeVisualIndicator? = null
init {
desktopMode = DesktopModeImpl()
@@ -298,6 +306,52 @@
}
/**
+ * Perform checks required on drag move. Create/release fullscreen indicator as needed.
+ *
+ * @param taskInfo the task being dragged.
+ * @param taskSurface SurfaceControl of dragged task.
+ * @param y coordinate of dragged task. Used for checks against status bar height.
+ */
+ fun onDragPositioningMove(
+ taskInfo: RunningTaskInfo,
+ taskSurface: SurfaceControl,
+ y: Float
+ ) {
+ val statusBarHeight = displayController
+ .getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
+ if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
+ if (y <= statusBarHeight && visualIndicator == null) {
+ visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
+ displayController, context, taskSurface, shellTaskOrganizer,
+ rootTaskDisplayAreaOrganizer)
+ visualIndicator?.createFullscreenIndicator()
+ } else if (y > statusBarHeight && visualIndicator != null) {
+ visualIndicator?.releaseFullscreenIndicator()
+ visualIndicator = null
+ }
+ }
+ }
+
+ /**
+ * Perform checks required on drag end. Move to fullscreen if drag ends in status bar area.
+ *
+ * @param taskInfo the task being dragged.
+ * @param y height of drag, to be checked against status bar height.
+ */
+ fun onDragPositioningEnd(
+ taskInfo: RunningTaskInfo,
+ y: Float
+ ) {
+ val statusBarHeight = displayController
+ .getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
+ if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
+ moveToFullscreen(taskInfo.taskId)
+ visualIndicator?.releaseFullscreenIndicator()
+ visualIndicator = null
+ }
+ }
+
+ /**
* Adds a listener to find out about changes in the visibility of freeform tasks.
*
* @param listener the listener to add.
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 748f4a19..582616d 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
@@ -163,6 +163,10 @@
this::onKeepClearAreasChangedCallback;
private void onKeepClearAreasChangedCallback() {
+ if (mIsKeyguardShowingOrAnimating) {
+ // early bail out if the change was caused by keyguard showing up
+ return;
+ }
if (!mEnablePipKeepClearAlgorithm) {
// early bail out if the keep clear areas feature is disabled
return;
@@ -188,6 +192,10 @@
// early bail out if the keep clear areas feature is disabled
return;
}
+ if (mIsKeyguardShowingOrAnimating) {
+ // early bail out if the change was caused by keyguard showing up
+ return;
+ }
// only move if we're in PiP or transitioning into PiP
if (!mPipTransitionState.shouldBlockResizeRequest()) {
Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
@@ -639,9 +647,11 @@
DisplayLayout pendingLayout = mDisplayController
.getDisplayLayout(mPipDisplayLayoutState.getDisplayId());
if (mIsInFixedRotation
+ || mIsKeyguardShowingOrAnimating
|| pendingLayout.rotation()
!= mPipBoundsState.getDisplayLayout().rotation()) {
- // bail out if there is a pending rotation or fixed rotation change
+ // bail out if there is a pending rotation or fixed rotation change or
+ // there's a keyguard present
return;
}
int oldMaxMovementBound = mPipBoundsState.getMovementBounds().bottom;
@@ -936,10 +946,10 @@
mPipBoundsState.getDisplayBounds().right,
mPipBoundsState.getDisplayBounds().bottom);
mPipBoundsState.addNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG, rect);
- updatePipPositionForKeepClearAreas();
} else {
mPipBoundsState.removeNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG);
}
+ updatePipPositionForKeepClearAreas();
}
private void setLauncherAppIconSize(int iconSizePx) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
index 23988a6..a7171fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
@@ -212,24 +212,25 @@
*/
@Override
public Size getSizeForAspectRatio(Size size, float aspectRatio) {
- // getting the percentage of the max size that current size takes
float currAspectRatio = (float) size.getWidth() / size.getHeight();
+
+ // getting the percentage of the max size that current size takes
Size currentMaxSize = getMaxSize(currAspectRatio);
float currentPercent = (float) size.getWidth() / currentMaxSize.getWidth();
// getting the max size for the target aspect ratio
Size updatedMaxSize = getMaxSize(aspectRatio);
- int width = (int) (updatedMaxSize.getWidth() * currentPercent);
- int height = (int) (updatedMaxSize.getHeight() * currentPercent);
+ int width = Math.round(updatedMaxSize.getWidth() * currentPercent);
+ int height = Math.round(updatedMaxSize.getHeight() * currentPercent);
// adjust the dimensions if below allowed min edge size
if (width < getMinEdgeSize() && aspectRatio <= 1) {
width = getMinEdgeSize();
- height = (int) (width / aspectRatio);
+ height = Math.round(width / aspectRatio);
} else if (height < getMinEdgeSize() && aspectRatio > 1) {
height = getMinEdgeSize();
- width = (int) (height * aspectRatio);
+ width = Math.round(height * aspectRatio);
}
// reduce the dimensions of the updated size to the calculated percentage
@@ -366,7 +367,7 @@
mPipDisplayLayoutState = pipDisplayLayoutState;
boolean enablePipSizeLargeScreen = SystemProperties
- .getBoolean("persist.wm.debug.enable_pip_size_large_screen", false);
+ .getBoolean("persist.wm.debug.enable_pip_size_large_screen", true);
// choose between two implementations of size spec logic
if (enablePipSizeLargeScreen) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
index 1a6c1d6..4048c5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
@@ -17,6 +17,11 @@
package com.android.wm.shell.recents;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.IRecentsAnimationRunner;
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
@@ -45,4 +50,10 @@
* Gets the set of running tasks.
*/
RunningTaskInfo[] getRunningTasks(int maxNum) = 4;
+
+ /**
+ * Starts a recents transition.
+ */
+ oneway void startRecentsTransition(in PendingIntent intent, in Intent fillIn, in Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) = 5;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 0d9faa3..c5bfd87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -24,13 +24,18 @@
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
+import android.view.IRecentsAnimationRunner;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
@@ -79,6 +84,7 @@
private final TaskStackListenerImpl mTaskStackListener;
private final RecentTasksImpl mImpl = new RecentTasksImpl();
private final ActivityTaskManager mActivityTaskManager;
+ private RecentsTransitionHandler mTransitionHandler = null;
private IRecentTasksListener mListener;
private final boolean mIsDesktopMode;
@@ -150,6 +156,10 @@
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTaskListener(this));
}
+ void setTransitionHandler(RecentsTransitionHandler handler) {
+ mTransitionHandler = handler;
+ }
+
/**
* Adds a split pair. This call does not validate the taskIds, only that they are not the same.
*/
@@ -492,5 +502,18 @@
true /* blocking */);
return tasks[0];
}
+
+ @Override
+ public void startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) {
+ if (mController.mTransitionHandler == null) {
+ Slog.e(TAG, "Used shell-transitions startRecentsTransition without"
+ + " shell-transitions");
+ return;
+ }
+ executeRemoteCallWithTaskPermission(mController, "startRecentsTransition",
+ (controller) -> controller.mTransitionHandler.startRecentsTransition(
+ intent, fillIn, options, appThread, listener));
+ }
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
new file mode 100644
index 0000000..db75be7
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -0,0 +1,780 @@
+/*
+ * Copyright (C) 2023 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.recents;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
+import static android.view.WindowManager.TRANSIT_SLEEP;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.view.IRecentsAnimationController;
+import android.view.IRecentsAnimationRunner;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
+import android.window.PictureInPictureSurfaceTransaction;
+import android.window.TaskSnapshot;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.TransitionUtil;
+
+import java.util.ArrayList;
+
+/**
+ * Handles the Recents (overview) animation. Only one of these can run at a time. A recents
+ * transition must be created via {@link #startRecentsTransition}. Anything else will be ignored.
+ */
+public class RecentsTransitionHandler implements Transitions.TransitionHandler {
+ private static final String TAG = "RecentsTransitionHandler";
+
+ private final Transitions mTransitions;
+ private final ShellExecutor mExecutor;
+ private IApplicationThread mAnimApp = null;
+ private final ArrayList<RecentsController> mControllers = new ArrayList<>();
+
+ /**
+ * List of other handlers which might need to mix recents with other things. These are checked
+ * in the order they are added. Ideally there should only be one.
+ */
+ private final ArrayList<RecentsMixedHandler> mMixers = new ArrayList<>();
+
+ public RecentsTransitionHandler(ShellInit shellInit, Transitions transitions,
+ @Nullable RecentTasksController recentTasksController) {
+ mTransitions = transitions;
+ mExecutor = transitions.getMainExecutor();
+ if (!Transitions.ENABLE_SHELL_TRANSITIONS) return;
+ if (recentTasksController == null) return;
+ shellInit.addInitCallback(() -> {
+ recentTasksController.setTransitionHandler(this);
+ transitions.addHandler(this);
+ }, this);
+ }
+
+ /** Register a mixer handler. {@see RecentsMixedHandler}*/
+ public void addMixer(RecentsMixedHandler mixer) {
+ mMixers.add(mixer);
+ }
+
+ /** Unregister a Mixed Handler */
+ public void removeMixer(RecentsMixedHandler mixer) {
+ mMixers.remove(mixer);
+ }
+
+ void startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) {
+ // only care about latest one.
+ mAnimApp = appThread;
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.sendPendingIntent(intent, fillIn, options);
+ final RecentsController controller = new RecentsController(listener);
+ RecentsMixedHandler mixer = null;
+ Transitions.TransitionHandler mixedHandler = null;
+ for (int i = 0; i < mMixers.size(); ++i) {
+ mixedHandler = mMixers.get(i).handleRecentsRequest(wct);
+ if (mixedHandler != null) {
+ mixer = mMixers.get(i);
+ break;
+ }
+ }
+ final IBinder transition = mTransitions.startTransition(TRANSIT_TO_FRONT, wct,
+ mixedHandler == null ? this : mixedHandler);
+ if (mixer != null) {
+ mixer.setRecentsTransition(transition);
+ }
+ if (transition == null) {
+ controller.cancel();
+ return;
+ }
+ controller.setTransition(transition);
+ mControllers.add(controller);
+ }
+
+ @Override
+ public WindowContainerTransaction handleRequest(IBinder transition,
+ TransitionRequestInfo request) {
+ // do not directly handle requests. Only entry point should be via startRecentsTransition
+ return null;
+ }
+
+ private int findController(IBinder transition) {
+ for (int i = mControllers.size() - 1; i >= 0; --i) {
+ if (mControllers.get(i).mTransition == transition) return i;
+ }
+ return -1;
+ }
+
+ @Override
+ public boolean startAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction startTransaction,
+ SurfaceControl.Transaction finishTransaction,
+ Transitions.TransitionFinishCallback finishCallback) {
+ final int controllerIdx = findController(transition);
+ if (controllerIdx < 0) return false;
+ final RecentsController controller = mControllers.get(controllerIdx);
+ Transitions.setRunningRemoteTransitionDelegate(mAnimApp);
+ mAnimApp = null;
+ if (!controller.start(info, startTransaction, finishTransaction, finishCallback)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void mergeAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction t, IBinder mergeTarget,
+ Transitions.TransitionFinishCallback finishCallback) {
+ final int targetIdx = findController(mergeTarget);
+ if (targetIdx < 0) return;
+ final RecentsController controller = mControllers.get(targetIdx);
+ controller.merge(info, t, finishCallback);
+ }
+
+ @Override
+ public void onTransitionConsumed(IBinder transition, boolean aborted,
+ SurfaceControl.Transaction finishTransaction) {
+ final int idx = findController(transition);
+ if (idx < 0) return;
+ mControllers.get(idx).cancel();
+ }
+
+ /** There is only one of these and it gets reset on finish. */
+ private class RecentsController extends IRecentsAnimationController.Stub {
+ private IRecentsAnimationRunner mListener;
+ private IBinder.DeathRecipient mDeathHandler;
+ private Transitions.TransitionFinishCallback mFinishCB = null;
+ private SurfaceControl.Transaction mFinishTransaction = null;
+
+ /**
+ * List of tasks that we are switching away from via this transition. Upon finish, these
+ * pausing tasks will become invisible.
+ * These need to be ordered since the order must be restored if there is no task-switch.
+ */
+ private ArrayList<TaskState> mPausingTasks = null;
+
+ /**
+ * List of tasks that we are switching to. Upon finish, these will remain visible and
+ * on top.
+ */
+ private ArrayList<TaskState> mOpeningTasks = null;
+
+ private WindowContainerToken mPipTask = null;
+ private WindowContainerToken mRecentsTask = null;
+ private int mRecentsTaskId = -1;
+ private TransitionInfo mInfo = null;
+ private boolean mOpeningSeparateHome = false;
+ private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
+ private PictureInPictureSurfaceTransaction mPipTransaction = null;
+ private IBinder mTransition = null;
+ private boolean mKeyguardLocked = false;
+ private boolean mWillFinishToHome = false;
+
+ /** The animation is idle, waiting for the user to choose a task to switch to. */
+ private static final int STATE_NORMAL = 0;
+
+ /** The user chose a new task to switch to and the animation is animating to it. */
+ private static final int STATE_NEW_TASK = 1;
+
+ /** The latest state that the recents animation is operating in. */
+ private int mState = STATE_NORMAL;
+
+ RecentsController(IRecentsAnimationRunner listener) {
+ mListener = listener;
+ mDeathHandler = () -> mExecutor.execute(() -> {
+ if (mListener == null) return;
+ if (mFinishCB != null) {
+ finish(mWillFinishToHome, false /* leaveHint */);
+ }
+ });
+ try {
+ mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */);
+ } catch (RemoteException e) {
+ mListener = null;
+ }
+ }
+
+ void setTransition(IBinder transition) {
+ mTransition = transition;
+ }
+
+ void cancel() {
+ // restoring (to-home = false) involves submitting more WM changes, so by default, use
+ // toHome = true when canceling.
+ cancel(true /* toHome */);
+ }
+
+ void cancel(boolean toHome) {
+ if (mListener != null) {
+ try {
+ mListener.onAnimationCanceled(null, null);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error canceling recents animation", e);
+ }
+ }
+ if (mFinishCB != null) {
+ finish(toHome, false /* userLeave */);
+ } else {
+ cleanUp();
+ }
+ }
+
+ /**
+ * Sends a cancel message to the recents animation with snapshots. Used to trigger a
+ * "replace-with-screenshot" like behavior.
+ */
+ private boolean sendCancelWithSnapshots() {
+ int[] taskIds = null;
+ TaskSnapshot[] snapshots = null;
+ if (mPausingTasks.size() > 0) {
+ taskIds = new int[mPausingTasks.size()];
+ snapshots = new TaskSnapshot[mPausingTasks.size()];
+ try {
+ for (int i = 0; i < mPausingTasks.size(); ++i) {
+ snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
+ mPausingTasks.get(0).mTaskInfo.taskId);
+ }
+ } catch (RemoteException e) {
+ taskIds = null;
+ snapshots = null;
+ }
+ }
+ try {
+ mListener.onAnimationCanceled(taskIds, snapshots);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error canceling recents animation", e);
+ return false;
+ }
+ return true;
+ }
+
+ void cleanUp() {
+ if (mListener != null && mDeathHandler != null) {
+ mListener.asBinder().unlinkToDeath(mDeathHandler, 0 /* flags */);
+ mDeathHandler = null;
+ }
+ mListener = null;
+ mFinishCB = null;
+ // clean-up leash surfacecontrols and anything that might reference them.
+ if (mLeashMap != null) {
+ for (int i = 0; i < mLeashMap.size(); ++i) {
+ mLeashMap.valueAt(i).release();
+ }
+ mLeashMap = null;
+ }
+ mFinishTransaction = null;
+ mPausingTasks = null;
+ mOpeningTasks = null;
+ mInfo = null;
+ mTransition = null;
+ mControllers.remove(this);
+ }
+
+ boolean start(TransitionInfo info, SurfaceControl.Transaction t,
+ SurfaceControl.Transaction finishT, Transitions.TransitionFinishCallback finishCB) {
+ if (mListener == null || mTransition == null) {
+ cleanUp();
+ return false;
+ }
+ // First see if this is a valid recents transition.
+ boolean hasPausingTasks = false;
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (TransitionUtil.isWallpaper(change)) continue;
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ hasPausingTasks = true;
+ continue;
+ }
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
+ mRecentsTask = taskInfo.token;
+ mRecentsTaskId = taskInfo.taskId;
+ } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ mRecentsTask = taskInfo.token;
+ mRecentsTaskId = taskInfo.taskId;
+ }
+ }
+ if (mRecentsTask == null && !hasPausingTasks) {
+ // Recents is already running apparently, so this is a no-op.
+ Slog.e(TAG, "Tried to start recents while it is already running.");
+ cleanUp();
+ return false;
+ }
+
+ mInfo = info;
+ mFinishCB = finishCB;
+ mFinishTransaction = finishT;
+ mPausingTasks = new ArrayList<>();
+ mOpeningTasks = new ArrayList<>();
+ mLeashMap = new ArrayMap<>();
+ mKeyguardLocked = (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0;
+
+ final ArrayList<RemoteAnimationTarget> apps = new ArrayList<>();
+ final ArrayList<RemoteAnimationTarget> wallpapers = new ArrayList<>();
+ TransitionUtil.LeafTaskFilter leafTaskFilter = new TransitionUtil.LeafTaskFilter();
+ // About layering: we divide up the "layer space" into 3 regions (each the size of
+ // the change count). This lets us categorize things into above/below/between
+ // while maintaining their relative ordering.
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (TransitionUtil.isWallpaper(change)) {
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
+ // wallpapers go into the "below" layer space
+ info.getChanges().size() - i, info, t, mLeashMap);
+ wallpapers.add(target);
+ // Make all the wallpapers opaque since we want them visible from the start
+ t.setAlpha(target.leash, 1);
+ } else if (leafTaskFilter.test(change)) {
+ // start by putting everything into the "below" layer space.
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
+ info.getChanges().size() - i, info, t, mLeashMap);
+ apps.add(target);
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ // raise closing (pausing) task to "above" layer so it isn't covered
+ t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ mPausingTasks.add(new TaskState(change, target.leash));
+ if (taskInfo.pictureInPictureParams != null
+ && taskInfo.pictureInPictureParams.isAutoEnterEnabled()) {
+ mPipTask = taskInfo.token;
+ }
+ } else if (taskInfo != null
+ && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
+ // There's a 3p launcher, so make sure recents goes above that.
+ t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // do nothing
+ } else if (TransitionUtil.isOpeningType(change.getMode())) {
+ mOpeningTasks.add(new TaskState(change, target.leash));
+ }
+ }
+ }
+ t.apply();
+ try {
+ mListener.onAnimationStart(this,
+ apps.toArray(new RemoteAnimationTarget[apps.size()]),
+ wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
+ new Rect(0, 0, 0, 0), new Rect());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error starting recents animation", e);
+ cancel();
+ }
+ return true;
+ }
+
+ @SuppressLint("NewApi")
+ void merge(TransitionInfo info, SurfaceControl.Transaction t,
+ Transitions.TransitionFinishCallback finishCallback) {
+ if (mFinishCB == null) {
+ // This was no-op'd (likely a repeated start) and we've already sent finish.
+ return;
+ }
+ if (info.getType() == TRANSIT_SLEEP) {
+ // A sleep event means we need to stop animations immediately, so cancel here.
+ cancel();
+ return;
+ }
+ ArrayList<TransitionInfo.Change> openingTasks = null;
+ ArrayList<TransitionInfo.Change> closingTasks = null;
+ mOpeningSeparateHome = false;
+ TransitionInfo.Change recentsOpening = null;
+ boolean foundRecentsClosing = false;
+ boolean hasChangingApp = false;
+ final TransitionUtil.LeafTaskFilter leafTaskFilter =
+ new TransitionUtil.LeafTaskFilter();
+ boolean hasTaskChange = false;
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ hasTaskChange = hasTaskChange || taskInfo != null;
+ final boolean isLeafTask = leafTaskFilter.test(change);
+ if (TransitionUtil.isOpeningType(change.getMode())) {
+ if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ recentsOpening = change;
+ } else if (isLeafTask) {
+ if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // This is usually a 3p launcher
+ mOpeningSeparateHome = true;
+ }
+ if (openingTasks == null) {
+ openingTasks = new ArrayList<>();
+ }
+ openingTasks.add(change);
+ }
+ } else if (TransitionUtil.isClosingType(change.getMode())) {
+ if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ foundRecentsClosing = true;
+ } else if (isLeafTask) {
+ if (closingTasks == null) {
+ closingTasks = new ArrayList<>();
+ }
+ closingTasks.add(change);
+ }
+ } else if (change.getMode() == TRANSIT_CHANGE) {
+ // Finish recents animation if the display is changed, so the default
+ // transition handler can play the animation such as rotation effect.
+ if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
+ cancel(mWillFinishToHome);
+ return;
+ }
+ hasChangingApp = true;
+ }
+ }
+ if (hasChangingApp && foundRecentsClosing) {
+ // This happens when a visible app is expanding (usually PiP). In this case,
+ // that transition probably has a special-purpose animation, so finish recents
+ // now and let it do its animation (since recents is going to be occluded).
+ sendCancelWithSnapshots();
+ mExecutor.executeDelayed(
+ () -> finishInner(true /* toHome */, false /* userLeaveHint */), 0);
+ return;
+ }
+ if (recentsOpening != null) {
+ // the recents task re-appeared. This happens if the user gestures before the
+ // task-switch (NEW_TASK) animation finishes.
+ if (mState == STATE_NORMAL) {
+ Slog.e(TAG, "Returning to recents while recents is already idle.");
+ }
+ if (closingTasks == null || closingTasks.size() == 0) {
+ Slog.e(TAG, "Returning to recents without closing any opening tasks.");
+ }
+ // Setup may hide it initially since it doesn't know that overview was still active.
+ t.show(recentsOpening.getLeash());
+ t.setAlpha(recentsOpening.getLeash(), 1.f);
+ mState = STATE_NORMAL;
+ }
+ boolean didMergeThings = false;
+ if (closingTasks != null) {
+ // Cancelling a task-switch. Move the tasks back to mPausing from mOpening
+ for (int i = 0; i < closingTasks.size(); ++i) {
+ final TransitionInfo.Change change = closingTasks.get(i);
+ int openingIdx = TaskState.indexOf(mOpeningTasks, change);
+ if (openingIdx < 0) {
+ Slog.e(TAG, "Back to existing recents animation from an unrecognized "
+ + "task: " + change.getTaskInfo().taskId);
+ continue;
+ }
+ mPausingTasks.add(mOpeningTasks.remove(openingIdx));
+ didMergeThings = true;
+ }
+ }
+ RemoteAnimationTarget[] appearedTargets = null;
+ if (openingTasks != null && openingTasks.size() > 0) {
+ // Switching to some new tasks, add to mOpening and remove from mPausing. Also,
+ // enter NEW_TASK state since this will start the switch-to animation.
+ final int layer = mInfo.getChanges().size() * 3;
+ appearedTargets = new RemoteAnimationTarget[openingTasks.size()];
+ for (int i = 0; i < openingTasks.size(); ++i) {
+ final TransitionInfo.Change change = openingTasks.get(i);
+ int pausingIdx = TaskState.indexOf(mPausingTasks, change);
+ if (pausingIdx >= 0) {
+ // Something is showing/opening a previously-pausing app.
+ appearedTargets[i] = TransitionUtil.newTarget(
+ change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ mOpeningTasks.add(mPausingTasks.remove(pausingIdx));
+ // Setup hides opening tasks initially, so make it visible again (since we
+ // are already showing it).
+ t.show(change.getLeash());
+ t.setAlpha(change.getLeash(), 1.f);
+ } else {
+ // We are receiving new opening tasks, so convert to onTasksAppeared.
+ appearedTargets[i] = TransitionUtil.newTarget(
+ change, layer, info, t, mLeashMap);
+ // reparent into the original `mInfo` since that's where we are animating.
+ final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
+ t.reparent(appearedTargets[i].leash, mInfo.getRoot(rootIdx).getLeash());
+ t.setLayer(appearedTargets[i].leash, layer);
+ mOpeningTasks.add(new TaskState(change, appearedTargets[i].leash));
+ }
+ }
+ didMergeThings = true;
+ mState = STATE_NEW_TASK;
+ }
+ if (!hasTaskChange) {
+ // Activity only transition, so consume the merge as it doesn't affect the rest of
+ // recents.
+ Slog.d(TAG, "Got an activity only transition during recents, so apply directly");
+ mergeActivityOnly(info, t);
+ } else if (!didMergeThings) {
+ // Didn't recognize anything in incoming transition so don't merge it.
+ Slog.w(TAG, "Don't know how to merge this transition.");
+ return;
+ }
+ // At this point, we are accepting the merge.
+ t.apply();
+ // not using the incoming anim-only surfaces
+ info.releaseAnimSurfaces();
+ finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ if (appearedTargets == null) return;
+ try {
+ mListener.onTasksAppeared(appearedTargets);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending appeared tasks to recents animation", e);
+ }
+ }
+
+ /** For now, just set-up a jump-cut to the new activity. */
+ private void mergeActivityOnly(TransitionInfo info, SurfaceControl.Transaction t) {
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (TransitionUtil.isOpeningType(change.getMode())) {
+ t.show(change.getLeash());
+ t.setAlpha(change.getLeash(), 1.f);
+ } else if (TransitionUtil.isClosingType(change.getMode())) {
+ t.hide(change.getLeash());
+ }
+ }
+ }
+
+ @Override
+ public TaskSnapshot screenshotTask(int taskId) {
+ try {
+ return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to screenshot task", e);
+ }
+ return null;
+ }
+
+ @Override
+ public void setInputConsumerEnabled(boolean enabled) {
+ mExecutor.execute(() -> {
+ if (mFinishCB == null || !enabled) return;
+ // transient launches don't receive focus automatically. Since we are taking over
+ // the gesture now, take focus explicitly.
+ // This also moves recents back to top if the user gestured before a switch
+ // animation finished.
+ try {
+ ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to set focused task", e);
+ }
+ });
+ }
+
+ @Override
+ public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
+ }
+
+ @Override
+ public void setFinishTaskTransaction(int taskId,
+ PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
+ mExecutor.execute(() -> {
+ if (mFinishCB == null) return;
+ mPipTransaction = finishTransaction;
+ });
+ }
+
+ @Override
+ @SuppressLint("NewApi")
+ public void finish(boolean toHome, boolean sendUserLeaveHint) {
+ mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint));
+ }
+
+ private void finishInner(boolean toHome, boolean sendUserLeaveHint) {
+ if (mFinishCB == null) {
+ Slog.e(TAG, "Duplicate call to finish");
+ return;
+ }
+ final Transitions.TransitionFinishCallback finishCB = mFinishCB;
+ mFinishCB = null;
+
+ final SurfaceControl.Transaction t = mFinishTransaction;
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+
+ if (mKeyguardLocked && mRecentsTask != null) {
+ if (toHome) wct.reorder(mRecentsTask, true /* toTop */);
+ else wct.restoreTransientOrder(mRecentsTask);
+ }
+ if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) {
+ // The gesture is returning to the pausing-task(s) rather than continuing with
+ // recents, so end the transition by moving the app back to the top (and also
+ // re-showing it's task).
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ // reverse order so that index 0 ends up on top
+ wct.reorder(mPausingTasks.get(i).mToken, true /* onTop */);
+ t.show(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (!mKeyguardLocked && mRecentsTask != null) {
+ wct.restoreTransientOrder(mRecentsTask);
+ }
+ } else if (toHome && mOpeningSeparateHome && mPausingTasks != null) {
+ // Special situation where 3p launcher was changed during recents (this happens
+ // during tapltests...). Here we get both "return to home" AND "home opening".
+ // This is basically going home, but we have to restore the recents and home order.
+ for (int i = 0; i < mOpeningTasks.size(); ++i) {
+ final TaskState state = mOpeningTasks.get(i);
+ if (state.mTaskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // Make sure it is on top.
+ wct.reorder(state.mToken, true /* onTop */);
+ }
+ t.show(state.mTaskSurface);
+ }
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ t.hide(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (!mKeyguardLocked && mRecentsTask != null) {
+ wct.restoreTransientOrder(mRecentsTask);
+ }
+ } else {
+ // The general case: committing to recents, going home, or switching tasks.
+ for (int i = 0; i < mOpeningTasks.size(); ++i) {
+ t.show(mOpeningTasks.get(i).mTaskSurface);
+ }
+ for (int i = 0; i < mPausingTasks.size(); ++i) {
+ if (!sendUserLeaveHint) {
+ // This means recents is not *actually* finishing, so of course we gotta
+ // do special stuff in WMCore to accommodate.
+ wct.setDoNotPip(mPausingTasks.get(i).mToken);
+ }
+ // Since we will reparent out of the leashes, pre-emptively hide the child
+ // surface to match the leash. Otherwise, there will be a flicker before the
+ // visibility gets committed in Core when using split-screen (in splitscreen,
+ // the leaf-tasks are not "independent" so aren't hidden by normal setup).
+ t.hide(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (mPipTask != null && mPipTransaction != null && sendUserLeaveHint) {
+ t.show(mInfo.getChange(mPipTask).getLeash());
+ PictureInPictureSurfaceTransaction.apply(mPipTransaction,
+ mInfo.getChange(mPipTask).getLeash(), t);
+ mPipTask = null;
+ mPipTransaction = null;
+ }
+ }
+ cleanUp();
+ finishCB.onTransitionFinished(wct.isEmpty() ? null : wct, null /* wctCB */);
+ }
+
+ @Override
+ public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
+ }
+
+ @Override
+ public void cleanupScreenshot() {
+ }
+
+ @Override
+ public void setWillFinishToHome(boolean willFinishToHome) {
+ mExecutor.execute(() -> {
+ mWillFinishToHome = willFinishToHome;
+ });
+ }
+
+ /**
+ * @see IRecentsAnimationController#removeTask
+ */
+ @Override
+ public boolean removeTask(int taskId) {
+ return false;
+ }
+
+ /**
+ * @see IRecentsAnimationController#detachNavigationBarFromApp
+ */
+ @Override
+ public void detachNavigationBarFromApp(boolean moveHomeToTop) {
+ mExecutor.execute(() -> {
+ if (mTransition == null) return;
+ try {
+ ActivityTaskManager.getService().detachNavigationBarFromApp(mTransition);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to detach the navigation bar from app", e);
+ }
+ });
+ }
+
+ /**
+ * @see IRecentsAnimationController#animateNavigationBarToApp(long)
+ */
+ @Override
+ public void animateNavigationBarToApp(long duration) {
+ }
+ };
+
+ /** Utility class to track the state of a task as-seen by recents. */
+ private static class TaskState {
+ WindowContainerToken mToken;
+ ActivityManager.RunningTaskInfo mTaskInfo;
+
+ /** The surface/leash of the task provided by Core. */
+ SurfaceControl mTaskSurface;
+
+ /** The (local) animation-leash created for this task. */
+ SurfaceControl mLeash;
+
+ TaskState(TransitionInfo.Change change, SurfaceControl leash) {
+ mToken = change.getContainer();
+ mTaskInfo = change.getTaskInfo();
+ mTaskSurface = change.getLeash();
+ mLeash = leash;
+ }
+
+ static int indexOf(ArrayList<TaskState> list, TransitionInfo.Change change) {
+ for (int i = list.size() - 1; i >= 0; --i) {
+ if (list.get(i).mToken.equals(change.getContainer())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public String toString() {
+ return "" + mToken + " : " + mLeash;
+ }
+ }
+
+ /**
+ * An interface for a mixed handler to receive information about recents requests (since these
+ * come into this handler directly vs from WMCore request).
+ */
+ public interface RecentsMixedHandler {
+ /**
+ * Called when a recents request comes in. The handler can add operations to outWCT. If
+ * the handler wants to "accept" the transition, it should return itself; otherwise, it
+ * should return `null`.
+ *
+ * If a mixed-handler accepts this recents, it will be the de-facto handler for this
+ * transition and is required to call the associated {@link #startAnimation},
+ * {@link #mergeAnimation}, and {@link #onTransitionConsumed} methods.
+ */
+ Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT);
+
+ /**
+ * Reports the transition token associated with the accepted recents request. If there was
+ * a problem starting the request, this will be called with `null`.
+ */
+ void setRecentsTransition(@Nullable IBinder transition);
+ }
+}
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 def945e..33cbdac 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
@@ -1335,7 +1335,7 @@
mMainStage.deactivate(finishedWCT, childrenToTop == mMainStage /* toTop */);
mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */);
finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
- setRootForceTranslucent(true, wct);
+ setRootForceTranslucent(true, finishedWCT);
finishedWCT.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
mSyncQueue.queue(finishedWCT);
mSyncQueue.runInSync(at -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index a841b7f..d6f4d6d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -220,12 +220,20 @@
mCallbacks.onNoLongerSupportMultiWindow();
return;
}
- mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
+ if (taskInfo.topActivity == null && mChildrenTaskInfo.contains(taskInfo.taskId)
+ && mChildrenTaskInfo.get(taskInfo.taskId).topActivity != null) {
+ // If top activity become null, it means the task is about to vanish, we use this
+ // signal to remove it from children list earlier for smooth dismiss transition.
+ mChildrenTaskInfo.remove(taskInfo.taskId);
+ mChildrenLeashes.remove(taskInfo.taskId);
+ } else {
+ mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
+ }
mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
taskInfo.isVisible);
- if (!ENABLE_SHELL_TRANSITIONS) {
- updateChildTaskSurface(
- taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
+ if (!ENABLE_SHELL_TRANSITIONS && mChildrenLeashes.contains(taskInfo.taskId)) {
+ updateChildTaskSurface(taskInfo, mChildrenLeashes.get(taskInfo.taskId),
+ false /* firstAppeared */);
}
} else {
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index aa851d1..586cab0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -43,6 +43,7 @@
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.splitscreen.StageCoordinator;
import com.android.wm.shell.sysui.ShellInit;
@@ -55,10 +56,12 @@
* A handler for dealing with transitions involving multiple other handlers. For example: an
* activity in split-screen going into PiP.
*/
-public class DefaultMixedHandler implements Transitions.TransitionHandler {
+public class DefaultMixedHandler implements Transitions.TransitionHandler,
+ RecentsTransitionHandler.RecentsMixedHandler {
private final Transitions mPlayer;
private PipTransitionController mPipHandler;
+ private RecentsTransitionHandler mRecentsHandler;
private StageCoordinator mSplitHandler;
private static class MixedTransition {
@@ -122,7 +125,8 @@
public DefaultMixedHandler(@NonNull ShellInit shellInit, @NonNull Transitions player,
Optional<SplitScreenController> splitScreenControllerOptional,
- Optional<PipTouchHandler> pipTouchHandlerOptional) {
+ Optional<PipTouchHandler> pipTouchHandlerOptional,
+ Optional<RecentsTransitionHandler> recentsHandlerOptional) {
mPlayer = player;
if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
&& splitScreenControllerOptional.isPresent()) {
@@ -134,6 +138,10 @@
if (mSplitHandler != null) {
mSplitHandler.setMixedHandler(this);
}
+ mRecentsHandler = recentsHandlerOptional.orElse(null);
+ if (mRecentsHandler != null) {
+ mRecentsHandler.addMixer(this);
+ }
}, this);
}
}
@@ -200,6 +208,29 @@
return null;
}
+ @Override
+ public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
+ if (mRecentsHandler != null && mSplitHandler.isSplitActive()) {
+ return this;
+ }
+ return null;
+ }
+
+ @Override
+ public void setRecentsTransition(IBinder transition) {
+ if (mSplitHandler.isSplitActive()) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
+ + "Split-Screen is active, so treat it as Mixed.");
+ final MixedTransition mixed = new MixedTransition(
+ MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
+ mixed.mLeftoversHandler = mRecentsHandler;
+ mActiveTransitions.add(mixed);
+ } else {
+ throw new IllegalStateException("Accepted a recents transition but don't know how to"
+ + " handle it");
+ }
+ }
+
private TransitionInfo subCopy(@NonNull TransitionInfo info,
@WindowManager.TransitionType int newType, boolean withChanges) {
final TransitionInfo out = new TransitionInfo(newType, withChanges ? info.getFlags() : 0);
@@ -561,6 +592,8 @@
mPipHandler.onTransitionConsumed(transition, aborted, finishT);
} else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
+ } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
+ mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index e643170..e632b56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -31,7 +31,6 @@
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Color;
-import android.graphics.ColorSpace;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
@@ -162,13 +161,12 @@
.setName("RotationLayer")
.build();
- final ColorSpace colorSpace = screenshotBuffer.getColorSpace();
+ TransitionAnimation.configureScreenshotLayer(t, mScreenshotLayer, screenshotBuffer);
final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
- t.setDataSpace(mScreenshotLayer, colorSpace.getDataSpace());
- t.setBuffer(mScreenshotLayer, hardwareBuffer);
t.show(mScreenshotLayer);
if (!isCustomRotate()) {
- mStartLuma = TransitionAnimation.getBorderLuma(hardwareBuffer, colorSpace);
+ mStartLuma = TransitionAnimation.getBorderLuma(hardwareBuffer,
+ screenshotBuffer.getColorSpace());
}
hardwareBuffer.close();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index b8b6d5b..b15802a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
@@ -541,9 +542,7 @@
}
}
- // Allow to notify keyguard un-occluding state to KeyguardService, which can happen while
- // screen-off, so there might no visibility change involved.
- if (info.getRootCount() == 0 && info.getType() != TRANSIT_KEYGUARD_UNOCCLUDE) {
+ if (info.getRootCount() == 0 && !alwaysReportToKeyguard(info)) {
// No root-leashes implies that the transition is empty/no-op, so just do
// housekeeping and return.
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots (%s): %s",
@@ -589,6 +588,23 @@
processReadyQueue();
}
+ /**
+ * Some transitions we always need to report to keyguard even if they are empty.
+ * TODO (b/274954192): Remove this once keyguard dispatching moves to Shell.
+ */
+ private static boolean alwaysReportToKeyguard(TransitionInfo info) {
+ // occlusion status of activities can change while screen is off so there will be no
+ // visibility change but we still need keyguardservice to be notified.
+ if (info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) return true;
+
+ // It's possible for some activities to stop with bad timing (esp. since we can't yet
+ // queue activity transitions initiated by apps) that results in an empty transition for
+ // keyguard going-away. In general, we should should always report Keyguard-going-away.
+ if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) return true;
+
+ return false;
+ }
+
void processReadyQueue() {
if (mReadyTransitions.isEmpty()) {
// Check if idle.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 6b45149..317b9a3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -166,7 +166,6 @@
}
decoration.relayout(taskInfo);
- setupCaptionColor(taskInfo, decoration);
}
@Override
@@ -252,7 +251,7 @@
}
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey();
- } else if (id == R.id.caption_handle) {
+ } else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
decoration.createHandleMenu();
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
@@ -262,7 +261,6 @@
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
decoration.closeHandleMenu();
- decoration.setButtonVisibility(false);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
}
@@ -302,7 +300,11 @@
return false;
}
case MotionEvent.ACTION_MOVE: {
+ final DesktopModeWindowDecoration decoration =
+ mWindowDecorByTaskId.get(mTaskId);
final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+ mDesktopTasksController.ifPresent(c -> c.onDragPositioningMove(taskInfo,
+ decoration.mTaskSurface, e.getRawY(dragPointerIdx)));
mDragPositioningCallback.onDragPositioningMove(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
mIsDragging = true;
@@ -311,18 +313,10 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
- final int statusBarHeight = mDisplayController
- .getDisplayLayout(taskInfo.displayId).stableInsets().top;
mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
- if (e.getRawY(dragPointerIdx) <= statusBarHeight) {
- if (DesktopModeStatus.isProto2Enabled()
- && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
- // Switch a single task to fullscreen
- mDesktopTasksController.ifPresent(
- c -> c.moveToFullscreen(taskInfo));
- }
- }
+ mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
+ e.getRawY(dragPointerIdx)));
final boolean wasDragging = mIsDragging;
mIsDragging = false;
return wasDragging;
@@ -556,13 +550,6 @@
}
}
- private void setupCaptionColor(RunningTaskInfo taskInfo,
- DesktopModeWindowDecoration decoration) {
- if (taskInfo == null || taskInfo.taskDescription == null) return;
- final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
- decoration.setCaptionColor(statusBarColor);
- }
-
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
return DesktopModeStatus.isProto2Enabled()
@@ -602,7 +589,6 @@
windowDecoration.setDragPositioningCallback(taskPositioner);
windowDecoration.setDragDetector(touchEventListener.mDragDetector);
windowDecoration.relayout(taskInfo, startT, finishT);
- setupCaptionColor(taskInfo, windowDecoration);
incrementEventReceiverTasks(taskInfo.displayId);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 3c0ef96..6478fe7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -22,15 +22,10 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.util.Log;
import android.view.Choreographer;
@@ -38,6 +33,7 @@
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.WindowContainerTransaction;
@@ -48,20 +44,24 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopTasksController;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
- * {@link DesktopModeWindowDecorViewModel}. The caption bar contains a handle, back button, and
- * close button.
+ * {@link DesktopModeWindowDecorViewModel}.
*
* The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
*/
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private static final String TAG = "DesktopModeWindowDecoration";
+
private final Handler mHandler;
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
+ private DesktopModeWindowDecorationViewHolder mWindowDecorViewHolder;
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
private DragPositioningCallback mDragPositioningCallback;
@@ -70,10 +70,11 @@
private RelayoutParams mRelayoutParams = new RelayoutParams();
private final int mCaptionMenuHeightId = R.dimen.freeform_decor_caption_menu_height;
+ private final int mCaptionMenuHeightWithoutWindowingControlsId =
+ R.dimen.freeform_decor_caption_menu_height_no_windowing_controls;
private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
new WindowDecoration.RelayoutResult<>();
- private boolean mDesktopActive;
private AdditionalWindow mHandleMenu;
private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
private final int mHandleMenuShadowRadiusId = R.dimen.caption_menu_shadow_radius;
@@ -94,7 +95,6 @@
mHandler = handler;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
- mDesktopActive = DesktopModeStatus.isActive(mContext);
}
@Override
@@ -152,9 +152,11 @@
final int outsetRightId = R.dimen.freeform_resize_handle;
final int outsetBottomId = R.dimen.freeform_resize_handle;
+ final int windowDecorLayoutId = getDesktopModeWindowDecorLayoutId(
+ taskInfo.getWindowingMode());
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo;
- mRelayoutParams.mLayoutResId = R.layout.desktop_mode_window_decor;
+ mRelayoutParams.mLayoutResId = windowDecorLayoutId;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
if (isDragResizeable) {
@@ -172,24 +174,28 @@
return;
}
if (oldRootView != mResult.mRootView) {
- setupRootView();
- }
-
- // If this task is not focused, do not show caption.
- setCaptionVisibility(mTaskInfo.isFocused);
-
- if (mTaskInfo.isFocused) {
- if (DesktopModeStatus.isProto2Enabled()) {
- updateButtonVisibility();
- } else if (DesktopModeStatus.isProto1Enabled()) {
- // Only handle should show if Desktop Mode is inactive.
- boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
- if (mDesktopActive != desktopCurrentStatus) {
- mDesktopActive = desktopCurrentStatus;
- setButtonVisibility(mDesktopActive);
- }
+ if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeFocusedWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else if (mRelayoutParams.mLayoutResId
+ == R.layout.desktop_mode_app_controls_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeAppControlsWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else {
+ throw new IllegalArgumentException("Unexpected layout resource id");
}
}
+ mWindowDecorViewHolder.bindData(mTaskInfo);
+
+ if (!mTaskInfo.isFocused) {
+ closeHandleMenu();
+ }
if (!isDragResizeable) {
closeDragResizeListener();
@@ -219,34 +225,14 @@
mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
}
- /**
- * Sets up listeners when a new root view is created.
- */
- private void setupRootView() {
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- caption.setOnTouchListener(mOnCaptionTouchListener);
- final View handle = caption.findViewById(R.id.caption_handle);
- handle.setOnTouchListener(mOnCaptionTouchListener);
- handle.setOnClickListener(mOnCaptionButtonClickListener);
- if (DesktopModeStatus.isProto1Enabled()) {
- final View back = caption.findViewById(R.id.back_button);
- back.setOnClickListener(mOnCaptionButtonClickListener);
- final View close = caption.findViewById(R.id.close_window);
- close.setOnClickListener(mOnCaptionButtonClickListener);
- }
- updateButtonVisibility();
- }
-
private void setupHandleMenu() {
final View menu = mHandleMenu.mWindowViewHost.getView();
final View fullscreen = menu.findViewById(R.id.fullscreen_button);
fullscreen.setOnClickListener(mOnCaptionButtonClickListener);
final View desktop = menu.findViewById(R.id.desktop_button);
- if (DesktopModeStatus.isProto2Enabled()) {
- desktop.setOnClickListener(mOnCaptionButtonClickListener);
- } else if (DesktopModeStatus.isProto1Enabled()) {
- desktop.setVisibility(View.GONE);
- }
+ desktop.setOnClickListener(mOnCaptionButtonClickListener);
+ final ViewGroup windowingBtns = menu.findViewById(R.id.windowing_mode_buttons);
+ windowingBtns.setVisibility(DesktopModeStatus.isProto1Enabled() ? View.GONE : View.VISIBLE);
final View split = menu.findViewById(R.id.split_screen_button);
split.setOnClickListener(mOnCaptionButtonClickListener);
final View close = menu.findViewById(R.id.close_button);
@@ -255,98 +241,26 @@
collapse.setOnClickListener(mOnCaptionButtonClickListener);
menu.setOnTouchListener(mOnCaptionTouchListener);
- String packageName = mTaskInfo.baseActivity.getPackageName();
- PackageManager pm = mContext.getApplicationContext().getPackageManager();
- // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
- PackageManager.ApplicationInfoFlags.of(0));
- final ImageView appIcon = menu.findViewById(R.id.application_icon);
- appIcon.setImageDrawable(pm.getApplicationIcon(applicationInfo));
- final TextView appName = menu.findViewById(R.id.application_name);
- appName.setText(pm.getApplicationLabel(applicationInfo));
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Package not found: " + packageName, e);
- }
- }
-
- /**
- * Sets caption visibility based on task focus.
- * Note: Only applicable to Desktop Proto 1; Proto 2 only closes handle menu on focus loss
- * @param visible whether or not the caption should be visible
- */
- private void setCaptionVisibility(boolean visible) {
- if (!visible) closeHandleMenu();
- if (!DesktopModeStatus.isProto1Enabled()) return;
- final int v = visible ? View.VISIBLE : View.GONE;
- final View captionView = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- captionView.setVisibility(v);
-
- }
-
- /**
- * Sets the visibility of buttons and color of caption based on desktop mode status
- */
- void updateButtonVisibility() {
- if (DesktopModeStatus.isProto2Enabled()) {
- setButtonVisibility(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM);
- } else if (DesktopModeStatus.isProto1Enabled()) {
- mDesktopActive = DesktopModeStatus.isActive(mContext);
- setButtonVisibility(mDesktopActive);
- }
- }
-
- /**
- * Show or hide buttons
- */
- void setButtonVisibility(boolean visible) {
- final int visibility = visible && DesktopModeStatus.isProto1Enabled()
- ? View.VISIBLE : View.GONE;
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- final View back = caption.findViewById(R.id.back_button);
- final View close = caption.findViewById(R.id.close_window);
- back.setVisibility(visibility);
- close.setVisibility(visibility);
- final int buttonTintColorRes =
- mDesktopActive ? R.color.decor_button_dark_color
- : R.color.decor_button_light_color;
- final ColorStateList buttonTintColor =
- caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
- final View handle = caption.findViewById(R.id.caption_handle);
- final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
- handleBackground.setTintList(buttonTintColor);
+ final ImageView appIcon = menu.findViewById(R.id.application_icon);
+ final TextView appName = menu.findViewById(R.id.application_name);
+ loadAppInfo(appName, appIcon);
}
boolean isHandleMenuActive() {
return mHandleMenu != null;
}
- void setCaptionColor(int captionColor) {
- if (mResult.mRootView == null) {
- return;
- }
-
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
- captionDrawable.setColor(captionColor);
-
- final int buttonTintColorRes =
- Color.valueOf(captionColor).luminance() < 0.5
- ? R.color.decor_button_light_color
- : R.color.decor_button_dark_color;
- final ColorStateList buttonTintColor =
- caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
-
- final View handle = caption.findViewById(R.id.caption_handle);
- final Drawable handleBackground = handle.getBackground();
- handleBackground.setTintList(buttonTintColor);
- if (DesktopModeStatus.isProto1Enabled()) {
- final View back = caption.findViewById(R.id.back_button);
- final Drawable backBackground = back.getBackground();
- backBackground.setTintList(buttonTintColor);
- final View close = caption.findViewById(R.id.close_window);
- final Drawable closeBackground = close.getBackground();
- closeBackground.setTintList(buttonTintColor);
+ private void loadAppInfo(TextView appNameTextView, ImageView appIconImageView) {
+ String packageName = mTaskInfo.realActivity.getPackageName();
+ PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ try {
+ // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0));
+ appNameTextView.setText(pm.getApplicationLabel(applicationInfo));
+ appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Package not found: " + packageName, e);
}
}
@@ -367,15 +281,26 @@
final int captionWidth = mTaskInfo.getConfiguration()
.windowConfiguration.getBounds().width();
final int menuWidth = loadDimensionPixelSize(resources, mHandleMenuWidthId);
- final int menuHeight = loadDimensionPixelSize(resources, mCaptionMenuHeightId);
+ // The windowing controls are disabled in proto1.
+ final int menuHeight = loadDimensionPixelSize(resources, DesktopModeStatus.isProto1Enabled()
+ ? mCaptionMenuHeightWithoutWindowingControlsId : mCaptionMenuHeightId);
final int shadowRadius = loadDimensionPixelSize(resources, mHandleMenuShadowRadiusId);
final int cornerRadius = loadDimensionPixelSize(resources, mHandleMenuCornerRadiusId);
- final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- - mResult.mDecorContainerOffsetX;
- final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ final int x, y;
+ if (mRelayoutParams.mLayoutResId
+ == R.layout.desktop_mode_app_controls_window_decor) {
+ // Align the handle menu to the left of the caption.
+ x = mRelayoutParams.mCaptionX - mResult.mDecorContainerOffsetX;
+ y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ } else {
+ // Position the handle menu at the center of the caption.
+ x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
+ - mResult.mDecorContainerOffsetX;
+ y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ }
mHandleMenuPosition.set(x, y);
- String namePrefix = "Caption Menu";
+ final String namePrefix = "Caption Menu";
mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
menuWidth, menuHeight, shadowRadius, cornerRadius);
mSyncQueue.runInSync(transaction -> {
@@ -503,6 +428,15 @@
super.close();
}
+ private int getDesktopModeWindowDecorLayoutId(int windowingMode) {
+ if (DesktopModeStatus.isProto1Enabled()) {
+ return R.layout.desktop_mode_app_controls_window_decor;
+ }
+ return windowingMode == WINDOWING_MODE_FREEFORM
+ ? R.layout.desktop_mode_app_controls_window_decor
+ : R.layout.desktop_mode_focused_window_decor;
+ }
+
static class Factory {
DesktopModeWindowDecoration create(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index ddd3b44..31e93ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -84,6 +84,7 @@
};
RunningTaskInfo mTaskInfo;
+ int mLayoutResId;
final SurfaceControl mTaskSurface;
Display mDisplay;
@@ -162,6 +163,8 @@
if (params.mRunningTaskInfo != null) {
mTaskInfo = params.mRunningTaskInfo;
}
+ final int oldLayoutResId = mLayoutResId;
+ mLayoutResId = params.mLayoutResId;
if (!mTaskInfo.isVisible) {
releaseViews();
@@ -178,7 +181,8 @@
final Configuration taskConfig = getConfigurationWithOverrides(mTaskInfo);
if (oldTaskConfig.densityDpi != taskConfig.densityDpi
|| mDisplay == null
- || mDisplay.getDisplayId() != mTaskInfo.displayId) {
+ || mDisplay.getDisplayId() != mTaskInfo.displayId
+ || oldLayoutResId != mLayoutResId) {
releaseViews();
if (!obtainDisplayOrRegisterListener()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..95b5051
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -0,0 +1,94 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.pm.PackageManager
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.util.Log
+import android.view.View
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
+ * finer controls such as a close window button and an "app info" section to pull up additional
+ * controls.
+ */
+internal class DesktopModeAppControlsWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: View = rootView.findViewById(R.id.caption_handle)
+ private val openMenuButton: View = rootView.findViewById(R.id.open_menu_button)
+ private val closeWindowButton: ImageButton = rootView.findViewById(R.id.close_window)
+ private val expandMenuButton: ImageButton = rootView.findViewById(R.id.expand_menu_button)
+ private val appNameTextView: TextView = rootView.findViewById(R.id.application_name)
+ private val appIconImageView: ImageView = rootView.findViewById(R.id.application_icon)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ openMenuButton.setOnClickListener(onCaptionButtonClickListener)
+ closeWindowButton.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ bindAppInfo(taskInfo)
+
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(taskInfo.taskDescription.statusBarColor)
+
+ closeWindowButton.imageTintList = ColorStateList.valueOf(
+ getCaptionCloseButtonColor(taskInfo))
+ expandMenuButton.imageTintList = ColorStateList.valueOf(
+ getCaptionExpandButtonColor(taskInfo))
+ appNameTextView.setTextColor(getCaptionAppNameTextColor(taskInfo))
+ }
+
+ private fun bindAppInfo(taskInfo: RunningTaskInfo) {
+ val packageName: String = taskInfo.realActivity.packageName
+ val pm: PackageManager = context.applicationContext.packageManager
+ try {
+ // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+ val applicationInfo = pm.getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0))
+ appNameTextView.text = pm.getApplicationLabel(applicationInfo)
+ appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo))
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Package not found: $packageName", e)
+ }
+ }
+
+ private fun getCaptionAppNameTextColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_app_name_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_app_name_dark)
+ }
+ }
+
+ private fun getCaptionCloseButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_close_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_close_button_dark)
+ }
+ }
+
+ private fun getCaptionExpandButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_expand_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_expand_button_dark)
+ }
+ }
+
+ companion object {
+ private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..47a12a0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
@@ -0,0 +1,44 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import android.widget.ImageButton
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen). It
+ * hosts a simple handle bar from which to initiate a drag motion to enter desktop mode.
+ */
+internal class DesktopModeFocusedWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: ImageButton = rootView.findViewById(R.id.caption_handle)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ val captionColor = taskInfo.taskDescription.statusBarColor
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(captionColor)
+
+ captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
+ }
+
+ private fun getCaptionHandleBarColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_dark)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..514ea52
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
@@ -0,0 +1,28 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.Context
+import android.graphics.Color
+import android.view.View
+
+/**
+ * Encapsulates the root [View] of a window decoration and its children to facilitate looking up
+ * children (via findViewById) and updating to the latest data from [RunningTaskInfo].
+ */
+internal abstract class DesktopModeWindowDecorationViewHolder(rootView: View) {
+ val context: Context = rootView.context
+
+ /**
+ * A signal to the view holder that new data is available and that the views should be updated
+ * to reflect it.
+ */
+ abstract fun bindData(taskInfo: RunningTaskInfo)
+
+ /**
+ * Whether the caption items should use the 'light' color variant so that there's good contrast
+ * with the caption background color.
+ */
+ protected fun shouldUseLightCaptionColors(taskInfo: RunningTaskInfo): Boolean {
+ return Color.valueOf(taskInfo.taskDescription.statusBarColor).luminance() < 0.5
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java
index 26b787f..a658375 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java
@@ -38,8 +38,15 @@
public TransitionInfoBuilder(@WindowManager.TransitionType int type,
@WindowManager.TransitionFlags int flags) {
+ this(type, flags, false /* asNoOp */);
+ }
+
+ public TransitionInfoBuilder(@WindowManager.TransitionType int type,
+ @WindowManager.TransitionFlags int flags, boolean asNoOp) {
mInfo = new TransitionInfo(type, flags);
- mInfo.addRootLeash(DISPLAY_ID, createMockSurface(true /* valid */), 0, 0);
+ if (!asNoOp) {
+ mInfo.addRootLeash(DISPLAY_ID, createMockSurface(true /* valid */), 0, 0);
+ }
}
public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index 47c9e06..3f79df6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -31,14 +31,12 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.TaskInfo;
-import android.content.Context;
-import android.content.SharedPreferences;
import android.graphics.Insets;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
+import android.util.Pair;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.SurfaceControlViewHost;
@@ -53,6 +51,7 @@
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.SyncTransactionQueue;
@@ -67,6 +66,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.function.Consumer;
+
/**
* Tests for {@link LetterboxEduWindowManager}.
*
@@ -80,8 +81,10 @@
private static final int USER_ID_1 = 1;
private static final int USER_ID_2 = 2;
- private static final String PREF_KEY_1 = String.valueOf(USER_ID_1);
- private static final String PREF_KEY_2 = String.valueOf(USER_ID_2);
+ private static final String TEST_COMPAT_UI_SHARED_PREFERENCES = "test_compat_ui_configuration";
+
+ private static final String TEST_HAS_SEEN_LETTERBOX_SHARED_PREFERENCES =
+ "test_has_seen_letterbox";
private static final int TASK_ID = 1;
@@ -103,46 +106,34 @@
@Mock private ShellTaskOrganizer.TaskListener mTaskListener;
@Mock private SurfaceControlViewHost mViewHost;
@Mock private Transitions mTransitions;
- @Mock private Runnable mOnDismissCallback;
+ @Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnDismissCallback;
@Mock private DockStateReader mDockStateReader;
- private SharedPreferences mSharedPreferences;
- @Nullable
- private Boolean mInitialPrefValue1 = null;
- @Nullable
- private Boolean mInitialPrefValue2 = null;
+ private CompatUIConfiguration mCompatUIConfiguration;
+ private TestShellExecutor mExecutor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mExecutor = new TestShellExecutor();
+ mCompatUIConfiguration = new CompatUIConfiguration(mContext, mExecutor) {
- mSharedPreferences = mContext.getSharedPreferences(
- LetterboxEduWindowManager.HAS_SEEN_LETTERBOX_EDUCATION_PREF_NAME,
- Context.MODE_PRIVATE);
- if (mSharedPreferences.contains(PREF_KEY_1)) {
- mInitialPrefValue1 = mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false);
- mSharedPreferences.edit().remove(PREF_KEY_1).apply();
- }
- if (mSharedPreferences.contains(PREF_KEY_2)) {
- mInitialPrefValue2 = mSharedPreferences.getBoolean(PREF_KEY_2, /* default= */ false);
- mSharedPreferences.edit().remove(PREF_KEY_2).apply();
- }
+ @Override
+ protected String getCompatUISharedPreferenceName() {
+ return TEST_COMPAT_UI_SHARED_PREFERENCES;
+ }
+
+ @Override
+ protected String getHasSeenLetterboxEducationSharedPreferencedName() {
+ return TEST_HAS_SEEN_LETTERBOX_SHARED_PREFERENCES;
+ }
+ };
}
@After
public void tearDown() {
- SharedPreferences.Editor editor = mSharedPreferences.edit();
- if (mInitialPrefValue1 == null) {
- editor.remove(PREF_KEY_1);
- } else {
- editor.putBoolean(PREF_KEY_1, mInitialPrefValue1);
- }
- if (mInitialPrefValue2 == null) {
- editor.remove(PREF_KEY_2);
- } else {
- editor.putBoolean(PREF_KEY_2, mInitialPrefValue2);
- }
- editor.apply();
+ mContext.deleteSharedPreferences(TEST_COMPAT_UI_SHARED_PREFERENCES);
+ mContext.deleteSharedPreferences(TEST_HAS_SEEN_LETTERBOX_SHARED_PREFERENCES);
}
@Test
@@ -166,8 +157,8 @@
@Test
public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
- LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
- true, USER_ID_1, /* isTaskbarEduShowing= */ true);
+ LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
+ USER_ID_1, /* isTaskbarEduShowing= */ true);
assertFalse(windowManager.createLayout(/* canShow= */ true));
@@ -180,7 +171,7 @@
assertTrue(windowManager.createLayout(/* canShow= */ false));
- assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ assertFalse(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
assertNull(windowManager.mLayout);
}
@@ -201,7 +192,7 @@
spyOn(dialogTitle);
// The education shouldn't be marked as seen until enter animation is done.
- assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ assertFalse(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
// Clicking the layout does nothing until enter animation is done.
layout.performClick();
verify(mAnimationController, never()).startExitAnimation(any(), any());
@@ -210,7 +201,7 @@
verifyAndFinishEnterAnimation(layout);
- assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ assertFalse(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
verify(dialogTitle).sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
// Exit animation should start following a click on the layout.
layout.performClick();
@@ -218,13 +209,16 @@
// Window manager isn't released until exit animation is done.
verify(windowManager, never()).release();
+ // After dismissed the user has seen the dialog
+ assertTrue(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
+
// Verify multiple clicks are ignored.
layout.performClick();
verifyAndFinishExitAnimation(layout);
verify(windowManager).release();
- verify(mOnDismissCallback).run();
+ verify(mOnDismissCallback).accept(any());
}
@Test
@@ -236,7 +230,10 @@
assertNotNull(windowManager.mLayout);
verifyAndFinishEnterAnimation(windowManager.mLayout);
- assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+
+ // We dismiss
+ windowManager.mLayout.findViewById(R.id.letterbox_education_dialog_dismiss_button)
+ .performClick();
windowManager.release();
windowManager = createWindowManager(/* eligible= */ true,
@@ -254,7 +251,7 @@
assertNotNull(windowManager.mLayout);
verifyAndFinishEnterAnimation(windowManager.mLayout);
- assertTrue(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ assertTrue(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
}
@Test
@@ -271,7 +268,7 @@
mRunOnIdleCaptor.getValue().run();
verify(mAnimationController, never()).startEnterAnimation(any(), any());
- assertFalse(mSharedPreferences.getBoolean(PREF_KEY_1, /* default= */ false));
+ assertFalse(mCompatUIConfiguration.getHasSeenLetterboxEducation(USER_ID_1));
}
@Test
@@ -297,7 +294,7 @@
mTaskListener, /* canShow= */ true));
verify(windowManager).release();
- verify(mOnDismissCallback, never()).run();
+ verify(mOnDismissCallback, never()).accept(any());
verify(mAnimationController, never()).startExitAnimation(any(), any());
assertNull(windowManager.mLayout);
}
@@ -395,8 +392,7 @@
}
private LetterboxEduWindowManager createWindowManager(boolean eligible, boolean isDocked) {
- return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */
- false, isDocked);
+ return createWindowManager(eligible, USER_ID_1, /* isTaskbarEduShowing= */ false, isDocked);
}
private LetterboxEduWindowManager createWindowManager(boolean eligible, int userId,
@@ -410,9 +406,8 @@
LetterboxEduWindowManager
windowManager = new LetterboxEduWindowManager(mContext,
createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener,
- createDisplayLayout(), mTransitions, mOnDismissCallback,
- mAnimationController, mDockStateReader);
-
+ createDisplayLayout(), mTransitions, mOnDismissCallback, mAnimationController,
+ mDockStateReader, mCompatUIConfiguration);
spyOn(windowManager);
doReturn(mViewHost).when(windowManager).createSurfaceViewHost();
doReturn(isTaskbarEduShowing).when(windowManager).isTaskbarEduShowing();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
new file mode 100644
index 0000000..0be08ba
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import android.testing.AndroidTestingRunner;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link LetterboxEduDialogLayout}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:ReachabilityEduLayoutTest
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ReachabilityEduLayoutTest extends ShellTestCase {
+
+ private ReachabilityEduLayout mLayout;
+ private View mMoveUpButton;
+ private View mMoveDownButton;
+ private View mMoveLeftButton;
+ private View mMoveRightButton;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLayout = (ReachabilityEduLayout) LayoutInflater.from(mContext)
+ .inflate(R.layout.reachability_ui_layout, null);
+ mMoveLeftButton = mLayout.findViewById(R.id.reachability_move_left_button);
+ mMoveRightButton = mLayout.findViewById(R.id.reachability_move_right_button);
+ mMoveUpButton = mLayout.findViewById(R.id.reachability_move_up_button);
+ mMoveDownButton = mLayout.findViewById(R.id.reachability_move_down_button);
+ }
+
+ @Test
+ public void testOnFinishInflate() {
+ assertNotNull(mMoveUpButton);
+ assertNotNull(mMoveDownButton);
+ assertNotNull(mMoveLeftButton);
+ assertNotNull(mMoveRightButton);
+ }
+
+ @Test
+ public void handleVisibility_activityNotLetterboxed_buttonsAreHidden() {
+ mLayout.handleVisibility(/* isActivityLetterboxed */ false,
+ /* letterboxVerticalPosition */ -1, /* letterboxHorizontalPosition */ -1,
+ /* availableWidth */ 0, /* availableHeight */ 0, /* fromDoubleTap */ false);
+ assertEquals(View.INVISIBLE, mMoveUpButton.getVisibility());
+ assertEquals(View.INVISIBLE, mMoveDownButton.getVisibility());
+ assertEquals(View.INVISIBLE, mMoveLeftButton.getVisibility());
+ assertEquals(View.INVISIBLE, mMoveRightButton.getVisibility());
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
new file mode 100644
index 0000000..91e1e19
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2023 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.compatui;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager;
+import android.app.TaskInfo;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestShellExecutor;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link ReachabilityEduWindowManager}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:ReachabilityEduWindowManagerTest
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class ReachabilityEduWindowManagerTest extends ShellTestCase {
+
+ private static final int USER_ID = 1;
+ private static final int TASK_ID = 1;
+
+ @Mock
+ private SyncTransactionQueue mSyncTransactionQueue;
+ @Mock
+ private ShellTaskOrganizer.TaskListener mTaskListener;
+ @Mock
+ private CompatUIController.CompatUICallback mCallback;
+ @Mock
+ private CompatUIConfiguration mCompatUIConfiguration;
+ @Mock
+ private DisplayLayout mDisplayLayout;
+
+ private TestShellExecutor mExecutor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mExecutor = new TestShellExecutor();
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testCreateLayout_notEligible_doesNotCreateLayout() {
+ final ReachabilityEduWindowManager windowManager = createReachabilityEduWindowManager(
+ createTaskInfo(/* userId= */ USER_ID, /*isLetterboxDoubleTapEnabled */ false));
+
+ assertFalse(windowManager.createLayout(/* canShow= */ true));
+
+ assertNull(windowManager.mLayout);
+ }
+
+ @Test
+ public void testCreateLayout_letterboxPositionChanged_doubleTapIsDetected() {
+ // Initial left position
+ final TaskInfo initialTaskInfo = createTaskInfoForHorizontalTapping(USER_ID, 0, 1000);
+ final ReachabilityEduWindowManager windowManager =
+ createReachabilityEduWindowManager(initialTaskInfo);
+ // Move to the right
+ final TaskInfo newPositionTaskInfo = createTaskInfoForHorizontalTapping(USER_ID, 1, 1000);
+ windowManager.updateCompatInfo(newPositionTaskInfo, mTaskListener, /* canShow */ true);
+
+ verify(mCompatUIConfiguration).setDontShowReachabilityEducationAgain(newPositionTaskInfo);
+ }
+
+
+ private ReachabilityEduWindowManager createReachabilityEduWindowManager(TaskInfo taskInfo) {
+ return new ReachabilityEduWindowManager(mContext, taskInfo,
+ mSyncTransactionQueue, mCallback, mTaskListener, mDisplayLayout,
+ mCompatUIConfiguration, mExecutor);
+ }
+
+ private static TaskInfo createTaskInfo(int userId, boolean isLetterboxDoubleTapEnabled) {
+ return createTaskInfo(userId, /* isLetterboxDoubleTapEnabled */ isLetterboxDoubleTapEnabled,
+ /* topActivityLetterboxVerticalPosition */ -1,
+ /* topActivityLetterboxHorizontalPosition */ -1,
+ /* topActivityLetterboxWidth */ -1,
+ /* topActivityLetterboxHeight */ -1);
+ }
+
+ private static TaskInfo createTaskInfoForHorizontalTapping(int userId,
+ int topActivityLetterboxHorizontalPosition, int topActivityLetterboxWidth) {
+ return createTaskInfo(userId, /* isLetterboxDoubleTapEnabled */ true,
+ /* topActivityLetterboxVerticalPosition */ -1,
+ topActivityLetterboxHorizontalPosition, topActivityLetterboxWidth,
+ /* topActivityLetterboxHeight */ -1);
+ }
+
+ private static TaskInfo createTaskInfo(int userId, boolean isLetterboxDoubleTapEnabled,
+ int topActivityLetterboxVerticalPosition, int topActivityLetterboxHorizontalPosition,
+ int topActivityLetterboxWidth, int topActivityLetterboxHeight) {
+ ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.userId = userId;
+ taskInfo.taskId = TASK_ID;
+ taskInfo.isLetterboxDoubleTapEnabled = isLetterboxDoubleTapEnabled;
+ taskInfo.topActivityLetterboxVerticalPosition = topActivityLetterboxVerticalPosition;
+ taskInfo.topActivityLetterboxHorizontalPosition = topActivityLetterboxHorizontalPosition;
+ taskInfo.topActivityLetterboxWidth = topActivityLetterboxWidth;
+ taskInfo.topActivityLetterboxHeight = topActivityLetterboxHeight;
+ return taskInfo;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 43f8f7b..63de74f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -41,6 +41,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.ActivityManager.RunningTaskInfo;
@@ -418,6 +419,17 @@
assertThat(wct).isNotNull();
}
+ @Test
+ public void testHandleTransitionRequest_taskOpen_doesNotStartAnotherTransition() {
+ RunningTaskInfo trigger = new RunningTaskInfo();
+ trigger.token = new MockToken().token();
+ trigger.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ mController.handleRequest(
+ mock(IBinder.class),
+ new TransitionRequestInfo(TRANSIT_OPEN, trigger, null /* remote */));
+ verifyZeroInteractions(mTransitions);
+ }
+
private DesktopModeController createController() {
return new DesktopModeController(mContext, mShellInit, mShellController,
mShellTaskOrganizer, mRootTaskDisplayAreaOrganizer, mTransitions,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 95e78a8..5cad50d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -37,11 +37,14 @@
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
@@ -73,7 +76,10 @@
@Mock lateinit var testExecutor: ShellExecutor
@Mock lateinit var shellController: ShellController
+ @Mock lateinit var displayController: DisplayController
@Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
+ @Mock lateinit var syncQueue: SyncTransactionQueue
+ @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
@Mock lateinit var transitions: Transitions
lateinit var mockitoSession: StaticMockitoSession
@@ -105,7 +111,10 @@
context,
shellInit,
shellController,
+ displayController,
shellTaskOrganizer,
+ syncQueue,
+ rootTaskDisplayAreaOrganizer,
transitions,
desktopModeTaskRepository,
TestShellExecutor()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 44f1f01..60d6978 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -1039,6 +1039,25 @@
verify(observer, times(0)).onTransitionFinished(eq(transitToken3), anyBoolean());
}
+ @Test
+ public void testEmptyTransitionStillReportsKeyguardGoingAway() {
+ Transitions transitions = createTestTransitions();
+ transitions.replaceDefaultHandlerForTest(mDefaultHandler);
+
+ IBinder transitToken = new Binder();
+ transitions.requestStartTransition(transitToken,
+ new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */));
+
+ // Make a no-op transition
+ TransitionInfo info = new TransitionInfoBuilder(
+ TRANSIT_OPEN, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, true /* noOp */).build();
+ transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class),
+ mock(SurfaceControl.Transaction.class));
+
+ // If keyguard-going-away flag set, then it shouldn't be aborted.
+ assertEquals(1, mDefaultHandler.activeCount());
+ }
+
class ChangeBuilder {
final TransitionInfo.Change mChange;
diff --git a/libs/hwui/MemoryPolicy.h b/libs/hwui/MemoryPolicy.h
index 41ced8c..139cdde 100644
--- a/libs/hwui/MemoryPolicy.h
+++ b/libs/hwui/MemoryPolicy.h
@@ -54,6 +54,7 @@
// collection
bool purgeScratchOnly = true;
// EXPERIMENTAL: Whether or not to trigger releasing GPU context when all contexts are stopped
+ // WARNING: Enabling this option can lead to instability, see b/266626090
bool releaseContextOnStoppedOnly = false;
};
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 9df6822..7af6efb 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -104,7 +104,7 @@
debugOverdraw = false;
std::string debugOverdrawProperty = base::GetProperty(PROPERTY_DEBUG_OVERDRAW, "");
if (debugOverdrawProperty != "") {
- INIT_LOGD(" Overdraw debug enabled: %s", debugOverdrawProperty);
+ INIT_LOGD(" Overdraw debug enabled: %s", debugOverdrawProperty.c_str());
if (debugOverdrawProperty == "show") {
debugOverdraw = true;
overdrawColorSet = OverdrawColorSet::Default;
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 28d78b4..914266d 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -579,17 +579,9 @@
LOG_ALWAYS_FATAL_IF(res == skcms_TFType_HLGinvish || res == skcms_TFType_Invalid);
jobject params;
- if (res == skcms_TFType_PQish || res == skcms_TFType_HLGish) {
- params = env->NewObject(gTransferParameters_class, gTransferParameters_constructorMethodID,
- transferParams.a, transferParams.b, transferParams.c,
- transferParams.d, transferParams.e, transferParams.f,
- transferParams.g, true);
- } else {
- params = env->NewObject(gTransferParameters_class, gTransferParameters_constructorMethodID,
- transferParams.a, transferParams.b, transferParams.c,
- transferParams.d, transferParams.e, transferParams.f,
- transferParams.g, false);
- }
+ params = env->NewObject(gTransferParameters_class, gTransferParameters_constructorMethodID,
+ transferParams.a, transferParams.b, transferParams.c, transferParams.d,
+ transferParams.e, transferParams.f, transferParams.g);
jfloatArray xyzArray = env->NewFloatArray(9);
jfloat xyz[9] = {
@@ -817,7 +809,7 @@
gTransferParameters_class = MakeGlobalRefOrDie(env, FindClassOrDie(env,
"android/graphics/ColorSpace$Rgb$TransferParameters"));
gTransferParameters_constructorMethodID =
- GetMethodIDOrDie(env, gTransferParameters_class, "<init>", "(DDDDDDDZ)V");
+ GetMethodIDOrDie(env, gTransferParameters_class, "<init>", "(DDDDDDD)V");
gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics");
gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 8efd180..b4fbc97 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6806,7 +6806,9 @@
/**
* @hide
- * Sets the computed sound dose value to {@code csd}
+ * Sets the computed sound dose value to {@code csd}. A negative value will
+ * reset all the CSD related timeouts: after a momentary exposure warning and
+ * before the momentary exposure reaches RS2 (see IEC62368-1 10.6.5)
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
@@ -6850,7 +6852,7 @@
/**
* @hide
- * Returns whether CSD is enabled on this device.
+ * Returns whether CSD is enabled and supported by the HAL on this device.
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
diff --git a/packages/CarrierDefaultApp/res/values-af/strings.xml b/packages/CarrierDefaultApp/res/values-af/strings.xml
index 64cc776..56dd89a 100644
--- a/packages/CarrierDefaultApp/res/values-af/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-af/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Diensverskafferkommunikasie"</string>
<string name="android_system_label" msgid="2797790869522345065">"Selfoondiensverskaffer"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiele data is op"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Jou mobiele data is gedeaktiveer"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Gaan in elk geval deur blaaier voort"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestasiehupstoot"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-opsies van jou diensverskaffer"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Besoek %s se webwerf om opsies vir jou appervaring te sien"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nie nou nie"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Bestuur"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Koop ’n prestasiehupstoot."</string>
diff --git a/packages/CarrierDefaultApp/res/values-am/strings.xml b/packages/CarrierDefaultApp/res/values-am/strings.xml
index 1bbc190..e626105 100644
--- a/packages/CarrierDefaultApp/res/values-am/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-am/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"የአገልግሎት አቅራቢ ግንኙነቶች"</string>
<string name="android_system_label" msgid="2797790869522345065">"የተንቀሳቃሽ ስልክ አገልግሎት አቅራቢ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"የተንቀሳቃሽ ስልክ ውሂብ አልቋል"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"የእርስዎ የተንቀሳቃሽ ስልክ ውሂብ ቦዝኗል"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"የአፈጻጸም ጭማሪ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5ጂ አማራጮች ከአገልግሎት አቅራቢዎ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ለመተግበሪያዎ ተሞክሮ አማራጮችን ለማየት የ%s ድር ጣቢያን ይጎብኙ"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"አሁን አይደለም"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"አስተዳድር"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"የአፈጻጸም ጭማሪ ይግዙ።"</string>
diff --git a/packages/CarrierDefaultApp/res/values-as/strings.xml b/packages/CarrierDefaultApp/res/values-as/strings.xml
index 56e2da5..860b82c 100644
--- a/packages/CarrierDefaultApp/res/values-as/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-as/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"বাহকৰ যোগাযোগ"</string>
<string name="android_system_label" msgid="2797790869522345065">"ম’বাইল সেৱা প্ৰদান কৰা কোম্পানী"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ম’বাইল ডেটা শেষ হৈছে"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"আপোনাৰ ম’বাইল ডেটা সেৱা নিষ্ক্ৰিয় কৰা হৈছে"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"তথাপিও ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"কাৰ্যক্ষমতা পৰিৱৰ্ধন"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"আপোনাৰ বাহকে আগবঢ়োৱা 5G বিকল্পসমূহ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"আপোনাৰ এপৰ অভিজ্ঞতাৰ বাবে বিকল্পসমূহ চাবলৈ %sৰ ৱেবছাইটলৈ যাওক"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এতিয়া নহয়"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"পৰিচালনা কৰক"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"এটা কাৰ্যক্ষমতা পৰিৱৰ্ধন ক্ৰয় কৰক।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-az/strings.xml b/packages/CarrierDefaultApp/res/values-az/strings.xml
index 9677b62..5be5740 100644
--- a/packages/CarrierDefaultApp/res/values-az/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-az/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operator Kommunikasiyaları"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobil Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobil data bitib"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil data deaktiv edilib"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Hər bir halda brazuer ilə davam edin"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performans artırması"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Operatorunuzdan 5G seçimləri"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Tətbiq təcrübəsi üzrə seçimlərə baxmaq üçün %s veb-saytına daxil olun"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"İndi yox"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"İdarə edin"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Performans artırması alın."</string>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index fc16b14..3d2e480 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Obaveštenja mobilnog operatera"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni podaci su potrošeni"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Poboljšanje učinka"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G opcije mobilnog operatera"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Opcije za doživljaj aplikacije potražite na veb-sajtu mobilnog operatera %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sada"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljaj"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite poboljšanje učinka."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bg/strings.xml b/packages/CarrierDefaultApp/res/values-bg/strings.xml
index 966ec33..95bd04b 100644
--- a/packages/CarrierDefaultApp/res/values-bg/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bg/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Съобщения от оператора"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобилен оператор"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилните данни са изразходвани"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилните ви данни са деактивирани"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Например страницата за вход може да не принадлежи на показаната организация."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Продължаване през браузър въпреки това"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Увеличаване на ефективността"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Опции за 5G от оператора ви"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"За да видите опции за практическата си работа с приложението, посетете уебсайта на %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сега"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управление"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купете пакет за увеличаване на ефективността."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bn/strings.xml b/packages/CarrierDefaultApp/res/values-bn/strings.xml
index 46eeb74..516dd89 100644
--- a/packages/CarrierDefaultApp/res/values-bn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bn/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"পরিষেবা প্রদানকারীর সাথে যোগাযোগ"</string>
<string name="android_system_label" msgid="2797790869522345065">"পরিষেবা প্রদানকারী"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"মোবাইল ডেটা ফুরিয়ে গেছে"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"আপনার মোবাইল ডেটা নিষ্ক্রিয় করা হয়েছে"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগ-ইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"যাই হোক, ব্রাউজারের মাধ্যমে চালিয়ে যান"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"পারফর্ম্যান্স বুস্ট"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"আপনার পরিষেবা প্রদানকারীর থেকে পাওয়া 5G বিকল্প"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"আপনার অ্যাপ সংক্রান্ত অভিজ্ঞতা উন্নত করার বিকল্পগুলি দেখতে, %s-এর ওয়েবসাইট ভিজিট করুন"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এখন নয়"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ম্যানেজ করুন"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"পারফর্ম্যান্স বুস্ট সংক্রান্ত ফিচার কিনুন।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-bs/strings.xml b/packages/CarrierDefaultApp/res/values-bs/strings.xml
index d41ad21..61d8dc8 100644
--- a/packages/CarrierDefaultApp/res/values-bs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bs/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikacije putem operatera"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni internet je potrošen"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Prijenos podataka na mobilnoj mreži je deaktiviran"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Naprimjer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko preglednika"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Pojačavanje performansi"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opcije 5G mreže operatera"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Posjetite web lokaciju operatera %s da vidite opcije za iskustvo u aplikaciji"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sada"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljajte"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite pojačavanje performansi."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml
index afde919..ec032d5 100644
--- a/packages/CarrierDefaultApp/res/values-ca/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicacions de l\'operador"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operador de telefonia mòbil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"S\'han esgotat les dades mòbils"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"S\'han desactivat les dades mòbils"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continua igualment mitjançant el navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimització de rendiment"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opcions 5G del teu operador"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visita el lloc web de %s per veure les opcions relacionades amb la teva experiència a l\'aplicació"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ara no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestiona"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compra una optimització de rendiment."</string>
diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml
index 65e2fd5..b4cdc56 100644
--- a/packages/CarrierDefaultApp/res/values-de/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-de/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Kommunikation mit Mobilfunkanbieter"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilfunkanbieter"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile Daten sind aufgebraucht"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Deine mobilen Daten wurden deaktiviert"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Trotzdem in einem Browser fortfahren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Leistungs-Boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-Optionen von deinem Mobilfunkanbieter"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Besuche die Website von %s, um dir die Optionen für deine App anzusehen"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nicht jetzt"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Verwalten"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Leistungs-Boost erwerben."</string>
diff --git a/packages/CarrierDefaultApp/res/values-el/strings.xml b/packages/CarrierDefaultApp/res/values-el/strings.xml
index 7a55d3a..8a6430d 100644
--- a/packages/CarrierDefaultApp/res/values-el/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-el/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Επικοινωνίες εταιρείας κινητής τηλεφωνίας"</string>
<string name="android_system_label" msgid="2797790869522345065">"Εταιρεία κινητής τηλεφωνίας"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Τα δεδομένα κινητής τηλεφωνίας εξαντλήθηκαν"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Τα δεδομένα κινητής τηλεφωνίας έχουν απενεργοποιηθεί"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ενίσχυση απόδοσης"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Επιλογές 5G από την εταιρεία κινητής τηλεφωνίας σας"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Επισκεφτείτε τον ιστότοπο %s για να δείτε επιλογές για την εμπειρία της εφαρμογής σας"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Όχι τώρα"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Διαχείριση"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Αγοράστε μια ενίσχυση απόδοσης."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
index 9d6b013..1f20896 100644
--- a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operator communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G options from your operator"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visit %s\'s website to see options for your app experience"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
index 00c0357..c084a0a 100644
--- a/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page may not belong to the organization shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G options from your carrier"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visit %s\'s website to see options for your app experience"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
index 9d6b013..1f20896 100644
--- a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operator communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G options from your operator"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visit %s\'s website to see options for your app experience"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
index 9d6b013..1f20896 100644
--- a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operator communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G options from your operator"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visit %s\'s website to see options for your app experience"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
index 7f7456d..0178925 100644
--- a/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page may not belong to the organization shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G options from your carrier"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visit %s\'s website to see options for your app experience"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
index 85598235..5bf0e6e 100644
--- a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicaciones de operadores"</string>
<string name="android_system_label" msgid="2797790869522345065">"Compañía de telefonía móvil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Se agotó el servicio de datos móviles"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Se desactivaron los datos móviles"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar de todos modos desde el navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de rendimiento"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opciones de 5G de tu operador"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visita el sitio web de %s para ver opciones de tu experiencia en la app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ahora no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Administrar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compra un aumento de rendimiento."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es/strings.xml b/packages/CarrierDefaultApp/res/values-es/strings.xml
index b9fa4c0..2a41c89 100644
--- a/packages/CarrierDefaultApp/res/values-es/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicaciones del operador"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operador de telefonía móvil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Se han agotado los datos móviles"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Se han desactivado los datos móviles"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar de todos modos a través del navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Mejora de rendimiento"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opciones 5G de tu operador"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visita el sitio web de %s para ver opciones relacionadas con tu experiencia en la aplicación"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ahora no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestionar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar una mejora de rendimiento."</string>
diff --git a/packages/CarrierDefaultApp/res/values-et/strings.xml b/packages/CarrierDefaultApp/res/values-et/strings.xml
index e51b76c..c1a33d0 100644
--- a/packages/CarrierDefaultApp/res/values-et/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-et/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobiilioperaator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiilse andmeside limiit on täis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Teie mobiilne andmeside on inaktiveeritud"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Jätka siiski brauseris"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Jõudluse võimendus"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G valikud teie operaatorilt"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Külastage operaatori %s veebisaiti, et näha oma rakenduse kasutuskogemuse valikuid"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Mitte praegu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Haldamine"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Ostke jõudluse võimendus."</string>
diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml
index 3650635..86e1291 100644
--- a/packages/CarrierDefaultApp/res/values-eu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operadorearekiko komunikazioa"</string>
<string name="android_system_label" msgid="2797790869522345065">"Telefonia mugikorreko operadorea"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Agortu egin da datu-konexioa"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Desaktibatu da datu-konexioa"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Jarraitu arakatzailearen bidez, halere"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Errendimendu-hobekuntza"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Operadoreak eskaintzen dituen 5G-aren aukerak"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Joan %s operadorearen webgunera aplikazioaren erabileraren inguruko aukerak ikusteko"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Orain ez"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kudeatu"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Erosi errendimendu-hobekuntza bat."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index 0738cbf..89c184c 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"ارتباطات شرکت مخابراتی"</string>
<string name="android_system_label" msgid="2797790869522345065">"شرکت مخابراتی دستگاه همراه"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"داده تلفن همراه تمام شده است"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"داده شبکه تلفن همراه شما غیرفعال شده است"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"درهر صورت ازطریق مرورگر ادامه یابد"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"تقویتکننده عملکرد"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"گزینههای نسل پنجم شرکت مخابراتی شما"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"برای دیدن گزینههای مرتبط با تجربه برنامه، به وبسایت %s مراجعه کنید"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"اکنون نه"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"مدیریت"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"تقویتکننده عملکرد خریداری کنید."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr/strings.xml b/packages/CarrierDefaultApp/res/values-fr/strings.xml
index 1d06a1d..4bc03ffa 100644
--- a/packages/CarrierDefaultApp/res/values-fr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Opérateur des communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Opérateur mobile"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Les données mobiles sont épuisées"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Les données mobiles ont été désactivées pour votre compte"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans le navigateur"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Boost de performances"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Options 5G de votre opérateur"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Accédez au site Web de %s pour consulter les options pour l\'expérience de votre appli"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Pas maintenant"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un boost de performances."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gu/strings.xml b/packages/CarrierDefaultApp/res/values-gu/strings.xml
index d003a44..1d42e8f 100644
--- a/packages/CarrierDefaultApp/res/values-gu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gu/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"મોબાઇલ ઑપરેટર તરફથી કમ્યુનિકેશન"</string>
<string name="android_system_label" msgid="2797790869522345065">"મોબાઇલ કૅરિઅર"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"મોબાઇલ ડેટા પૂરો થઈ ગયો છે"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"તમારો મોબાઇલ ડેટા નિષ્ક્રિય કરવામાં આવ્યો છે"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ બતાવવામાં આવેલી સંસ્થાનું ન પણ હોય."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"તો પણ બ્રાઉઝર મારફતે ચાલુ રાખો"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"પર્ફોર્મન્સ બૂસ્ટ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"તમારા મોબાઇલ ઑપરેટર તરફથી 5G વિકલ્પો"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"તમારા ઍપ અનુભવ માટેના વિકલ્પો જોવા માટે %sની વેબસાઇટની મુલાકાત લો"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"હમણાં નહીં"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"મેનેજ કરો"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"પર્ફોર્મન્સ બૂસ્ટ ખરીદો."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hi/strings.xml b/packages/CarrierDefaultApp/res/values-hi/strings.xml
index 6b3c544..a830d77 100644
--- a/packages/CarrierDefaultApp/res/values-hi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hi/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"मोबाइल सेवा देने वाली कंपनी"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा खत्म हो गया है"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"आपका मोबाइल डेटा बंद कर दिया गया है"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरण के लिए, हो सकता है कि लॉगिन पेज दिखाए गए संगठन का ना हो."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ब्राउज़र के ज़रिए किसी भी तरह जारी रखें"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफ़ॉर्मेंस बूस्ट"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी से मिले 5G के विकल्प"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ऐप्लिकेशन का बेहतर अनुभव पाने के लिए, %s की वेबसाइट पर जाकर विकल्प देखें"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"अभी नहीं"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"मैनेज करें"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"कोई परफ़ॉर्मेंस बूस्ट खरीदें."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hr/strings.xml b/packages/CarrierDefaultApp/res/values-hr/strings.xml
index 1a58080..34bf601 100644
--- a/packages/CarrierDefaultApp/res/values-hr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hr/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikacije operatera"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni su podaci potrošeni"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilni su podaci deaktivirani"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi putem preglednika"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Poboljšanje izvedbe"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opcije 5G mreže vašeg operatera"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Posjetite web-lokaciju %s za prikaz opcija za doživljaj aplikacije"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sad"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljajte"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite poboljšanje izvedbe."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hu/strings.xml b/packages/CarrierDefaultApp/res/values-hu/strings.xml
index 6ed1efe..13ac0a16 100644
--- a/packages/CarrierDefaultApp/res/values-hu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hu/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Szolgáltatói értesítések"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilszolgáltató"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Elérte a rendelkezésre álló mobiladat-mennyiséget"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"A rendszer deaktiválta a mobiladat-forgalmat"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Például lehetséges, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Folytatás ennek ellenére böngészőn keresztül"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Teljesítménynövelés"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-beállítások a szolgáltatótól"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"A(z) %s webhelyén megtekintheti az alkalmazás által nyújtott élményekhez tartozó beállításokat"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Most nem"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kezelés"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Vásároljon teljesítménynövelést."</string>
diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml
index cb0f35b..f9a9732 100644
--- a/packages/CarrierDefaultApp/res/values-in/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-in/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikasi Operator"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operator Seluler"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data seluler telah habis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data seluler telah dinonaktifkan"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Misalnya, halaman login mungkin bukan milik organisasi yang ditampilkan."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Tetap lanjutkan melalui browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Penguat sinyal"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opsi 5G dari operator Anda"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Buka situs %s untuk melihat opsi pengalaman aplikasi Anda"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Lain kali"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kelola"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Beli penguat sinyal."</string>
diff --git a/packages/CarrierDefaultApp/res/values-is/strings.xml b/packages/CarrierDefaultApp/res/values-is/strings.xml
index 1e5fa78..ca9d6c7 100644
--- a/packages/CarrierDefaultApp/res/values-is/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-is/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Samskipti við símafyrirtæki"</string>
<string name="android_system_label" msgid="2797790869522345065">"Símafyrirtæki"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Farsímagögn kláruðust"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Slökkt hefur verið á farsímagögnum"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Halda samt áfram í vafra"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Afkastaaukning"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-valkostir frá símafyrirtækinu"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Opnaðu vefsvæði %s til að sjá valkosti varðandi upplifun í forritinu"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ekki núna"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Stjórna"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kaupa afkastaaukningu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-iw/strings.xml b/packages/CarrierDefaultApp/res/values-iw/strings.xml
index 3551acf..9e5a8b5 100644
--- a/packages/CarrierDefaultApp/res/values-iw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-iw/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"מידע מהספק"</string>
<string name="android_system_label" msgid="2797790869522345065">"ספק שירות לנייד"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ניצלת את מכסת הנתונים הסלולריים"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"חבילת הגלישה שלך הושבתה"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"המשך בכל זאת באמצעות דפדפן"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"שיפור ביצועים"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"אפשרויות של רשת 5G מהספק"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ניתן להיכנס לאתר של %s כדי לראות אפשרויות נוספות לחוויית השימוש באפליקציה"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"לא עכשיו"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ניהול"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"רכישת שיפור ביצועים."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ka/strings.xml b/packages/CarrierDefaultApp/res/values-ka/strings.xml
index ee281d7..4488a55 100644
--- a/packages/CarrierDefaultApp/res/values-ka/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ka/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"ოპერატორთან კომუნიკაცია"</string>
<string name="android_system_label" msgid="2797790869522345065">"მობილური ოპერატორი"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"მობილური ინტერნეტის პაკეტი ამოიწურა"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"მობილური ინტერნეტი დეაქტივირებულია"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"მაინც ბრაუზერში გაგრძელება"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ეფექტურობის გაძლიერება"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G ვარიანტები თქვენი ოპერატორისგან"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ეწვიეთ %s-ის ვებსაიტს თქვენი აპის გამოცდილების ვარიანტების სანახავად"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ახლა არა"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"მართვა"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ეფექტურობის გაძლიერების შეძენა."</string>
diff --git a/packages/CarrierDefaultApp/res/values-kk/strings.xml b/packages/CarrierDefaultApp/res/values-kk/strings.xml
index b5f6950..ad91c79 100644
--- a/packages/CarrierDefaultApp/res/values-kk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kk/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Оператор байланыстары"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобильдік байланыс операторы"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобильдік интернет бітті"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильдік интернет өшірілді"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Бәрібір браузер арқылы жалғастыру"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Өнімділікті арттыру"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Оператор ұсынған 5G опциялары"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Қолданбаның жұмысына арналған опцияларды көру үшін %s веб-сайтына кіріңіз."</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Қазір емес"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Басқару"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Өнімділікті арттыру құралын сатып алыңыз."</string>
diff --git a/packages/CarrierDefaultApp/res/values-km/strings.xml b/packages/CarrierDefaultApp/res/values-km/strings.xml
index 20199a7..1852489 100644
--- a/packages/CarrierDefaultApp/res/values-km/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-km/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"ទំនាក់ទំនងរបស់ក្រុមហ៊ុនសេវាទូរសព្ទ"</string>
<string name="android_system_label" msgid="2797790869522345065">"ក្រុមហ៊ុនបម្រើសេវាទូរសព្ទចល័ត"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ទិន្នន័យចល័តបានអស់ហើយ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ទិន្នន័យចល័តរបស់អ្នកត្រូវបានបិទដំណើរការហើយ"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ឧទាហរណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ការបង្កើនប្រតិបត្តិការ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"ជម្រើស 5G ពីក្រុមហ៊ុនសេវាទូរសព្ទរបស់អ្នក"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ចូលទៅកាន់គេហទំព័ររបស់ %s ដើម្បីមើលជម្រើសសម្រាប់បទពិសោធន៍ប្រើកម្មវិធីរបស់អ្នក"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"កុំទាន់"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"គ្រប់គ្រង"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ទិញការបង្កើនប្រតិបត្តិការ។"</string>
diff --git a/packages/CarrierDefaultApp/res/values-kn/strings.xml b/packages/CarrierDefaultApp/res/values-kn/strings.xml
index 619b92a..bc3e1cc 100644
--- a/packages/CarrierDefaultApp/res/values-kn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kn/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"ವಾಹಕ ಸಂವಹನಗಳು"</string>
<string name="android_system_label" msgid="2797790869522345065">"ಮೊಬೈಲ್ ವಾಹಕ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ಮೊಬೈಲ್ ಡೇಟಾ ಮುಗಿದುಹೋಗಿದೆ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ನಿಮ್ಮ ಮೊಬೈಲ್ ಡೇಟಾ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿಲ್ಲದಿರಬಹುದು."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ಪರವಾಗಿಲ್ಲ, ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ಕಾರ್ಯಕ್ಷಮತೆ ಬೂಸ್ಟ್"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"ನಿಮ್ಮ ವಾಹಕದಿಂದ 5G ಆಯ್ಕೆಗಳು"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ನಿಮ್ಮ ಆ್ಯಪ್ ಅನುಭವಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ನೋಡಲು %s ನ ವೆಬ್ಸೈಟ್ಗೆ ಭೇಟಿ ನೀಡಿ"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ಈಗ ಬೇಡ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ನಿರ್ವಹಿಸಿ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ಕಾರ್ಯಕ್ಷಮತೆ ಬೂಸ್ಟ್ ಅನ್ನು ಖರೀದಿಸಿ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ko/strings.xml b/packages/CarrierDefaultApp/res/values-ko/strings.xml
index 46e172d..4e82d25 100644
--- a/packages/CarrierDefaultApp/res/values-ko/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ko/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"이동통신사 커뮤니케이션"</string>
<string name="android_system_label" msgid="2797790869522345065">"이동통신사"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"모바일 데이터가 소진되었습니다."</string>
<string name="no_data_notification_id" msgid="668400731803969521">"모바일 데이터가 비활성화되었습니다."</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"브라우저를 통해 계속하기"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"성능 향상"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"이동통신사의 5G 옵션"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"%s 웹사이트에 방문하여 앱 환경에 관한 옵션을 확인하세요."</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"나중에"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"관리"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"성능 향상 구매"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ky/strings.xml b/packages/CarrierDefaultApp/res/values-ky/strings.xml
index f2a96bc..aa6a132 100644
--- a/packages/CarrierDefaultApp/res/values-ky/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ky/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Байланыш операторунун билдирмелери"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобилдик байланыш оператору"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилдик Интернетиңиздин трафиги түгөндү"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилдик Интернет өчүрүлгөн"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Мисалы, аккаунтка кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Баары бир серепчи аркылуу улантуу"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Иштин майнаптуулугун жогорулатуу"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Байланыш операторунун 5G варианттары"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Колдонмону иштетүү параметрлерин көрүү үчүн %s сайтына өтүңүз"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Азыр эмес"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Тескөө"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Иштин майнаптуулугун жогорулатууну сатып алыңыз."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lo/strings.xml b/packages/CarrierDefaultApp/res/values-lo/strings.xml
index 28af830..0624c72 100644
--- a/packages/CarrierDefaultApp/res/values-lo/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lo/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"ການສື່ສານຈາກຜູ້ໃຫ້ບໍລິການ"</string>
<string name="android_system_label" msgid="2797790869522345065">"ຜູ້ໃຫ້ບໍລິການມືຖື"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ອິນເຕີເນັດມືຖືໝົດແລ້ວ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ປິດການນຳໃຊ້ອິນເຕີເນັດມືຖືຂອງທ່ານແລ້ວ"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ຕົວຢ່າງ, ໜ້າເຂົ້າສູ່ລະບົບອາດຈະບໍ່ແມ່ນຂອງອົງກອນທີ່ປາກົດ."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ດຳເນີນການຕໍ່ຜ່ານໂປຣແກຣມທ່ອງເວັບ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ເລັ່ງປະສິດທິພາບ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"ຕົວເລືອກ 5G ຈາກຜູ້ໃຫ້ບໍລິການຂອງທ່ານ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ເບິ່ງຕົວເລືອກຕ່າງໆສຳລັບປະສົບການການນຳໃຊ້ແອັບຂອງທ່ານໄດ້ຢູ່ເວັບໄຊຂອງ %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ບໍ່ຟ້າວເທື່ອ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ຈັດການ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ຊື້ການເລັ່ງປະສິດທິພາບ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lt/strings.xml b/packages/CarrierDefaultApp/res/values-lt/strings.xml
index b9be333..8780eb0 100644
--- a/packages/CarrierDefaultApp/res/values-lt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lt/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operatoriaus pranešimai"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobiliojo ryšio operatorius"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiliojo ryšio duomenys baigėsi"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobiliojo ryšio duomenys išaktyvinti"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vis tiek tęsti naudojant naršyklę"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Našumo pagerinimas"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Operatoriaus teikiamos 5G parinktys"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Apsilankykite „%s“ svetainėje ir peržiūrėkite programos funkcijų parinktis"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne dabar"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Tvarkyti"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Įsigykite našumo pagerinimo paslaugą."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lv/strings.xml b/packages/CarrierDefaultApp/res/values-lv/strings.xml
index d539947..a65fa58 100644
--- a/packages/CarrierDefaultApp/res/values-lv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lv/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Paziņojumi no mobilo sakaru operatora"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilo sakaru operators"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Sasniegts mobilo datu ierobežojums."</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Jūsu mobilie dati ir deaktivizēti"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Tomēr turpināt, izmantojot pārlūkprogrammu"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Veiktspējas uzlabojums"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Mobilo sakaru operatora piedāvātās 5G iespējas"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Apmeklējiet operatora %s vietni, lai skatītu pieejamās iespējas lietotnē"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Vēlāk"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Pārvaldīt"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Iegādājieties veiktspējas uzlabojumu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mk/strings.xml b/packages/CarrierDefaultApp/res/values-mk/strings.xml
index 4efecb0..4965d56 100644
--- a/packages/CarrierDefaultApp/res/values-mk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mk/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Комуникации со давателот на услугата"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобилен оператор"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилниот интернет е искористен"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилниот интернет ви е деактивиран"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страницата за најавување може да не припаѓа на прикажаната организација."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Сепак продолжи преку прелистувач"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Засилување на изведбата"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G опции од вашиот давател на услуга"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Посетете го веб-сајтот на %s за да ги видите опциите за искуството со апликацијата"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сега"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управувајте"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купете засилување на изведбата."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ml/strings.xml b/packages/CarrierDefaultApp/res/values-ml/strings.xml
index f4c19a3..cfeacbe 100644
--- a/packages/CarrierDefaultApp/res/values-ml/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ml/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"സേവനദാതാവ് നടത്തുന്ന ആശയവിനിമയങ്ങൾ"</string>
<string name="android_system_label" msgid="2797790869522345065">"മൊബൈൽ കാരിയർ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"മൊബൈൽ ഡാറ്റ തീർന്നിരിക്കുന്നു"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"നിങ്ങളുടെ മൊബൈൽ ഡാറ്റ നിർജീവമാക്കി"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"പ്രകടന ബൂസ്റ്റ്"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"നിങ്ങളുടെ സേവനദാതാവിൽ നിന്നുള്ള 5G ഓപ്ഷനുകൾ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"നിങ്ങളുടെ ആപ്പ് അനുഭവം സംബന്ധിച്ച ഓപ്ഷനുകൾക്ക് %s എന്നതിന്റെ വെബ്സൈറ്റ് സന്ദർശിക്കുക"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ഇപ്പോൾ വേണ്ട"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"മാനേജ് ചെയ്യുക"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"പ്രകടന ബൂസ്റ്റ് വാങ്ങൂ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mn/strings.xml b/packages/CarrierDefaultApp/res/values-mn/strings.xml
index 2f33eb2..3476ff0 100644
--- a/packages/CarrierDefaultApp/res/values-mn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mn/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Оператор компанийн харилцаа холбоо"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобайл оператор компани"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобайл дата дууссан"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Таны мобайл датаг идэвхгүй болгосон"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Жишээлбэл нэвтрэх хуудас нь харагдаж буй байгууллагынх биш байж болно."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ямар ч тохиолдолд хөтчөөр үргэлжлүүлэх"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Гүйцэтгэлийн идэвхжүүлэлт"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Таны оператор компанийн 5G сонголт"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Аппын хэрэглээнийхээ сонголтыг харахын тулд %s-н вебсайтад зочилно уу"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Одоо биш"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Удирдах"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Гүйцэтгэлийн идэвхжүүлэлтийг худалдаж аваарай."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index 9414545..4123045 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"वाहकसह संभाषणे"</string>
<string name="android_system_label" msgid="2797790869522345065">"मोबाइल वाहक"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा संपला आहे"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"तुमचा मोबाइल डेटा निष्क्रिय केला गेला"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पृष्ठ दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"तरीही ब्राउझरद्वारे सुरू ठेवा"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफॉर्मन्स बूस्ट"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"तुमच्या वाहकाकडून 5G पर्याय"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"तुमच्या अॅप अनुभवासाठी पर्याय पाहण्याकरिता %s च्या वेबसाइटला भेट द्या"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"आता नको"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"व्यवस्थापित करा"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"परफॉर्मन्स बूस्ट खरेदी करा."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ms/strings.xml b/packages/CarrierDefaultApp/res/values-ms/strings.xml
index 4fb377e..004d092 100644
--- a/packages/CarrierDefaultApp/res/values-ms/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ms/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikasi Pembawa"</string>
<string name="android_system_label" msgid="2797790869522345065">"Pembawa Mudah Alih"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data mudah alih telah habis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data mudah alih anda telah dinyahaktifkan"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Teruskan juga melalui penyemak imbas"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Peningkatan prestasi"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Pilihan 5G daripada pembawa anda"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Lawati laman web %s untuk melihat pilihan pengalaman apl anda"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Bukan sekarang"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Urus"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Beli perangsang prestasi."</string>
diff --git a/packages/CarrierDefaultApp/res/values-my/strings.xml b/packages/CarrierDefaultApp/res/values-my/strings.xml
index 002edd8..6e1381f 100644
--- a/packages/CarrierDefaultApp/res/values-my/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-my/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"မိုဘိုင်းဖုန်းကုမ္ပဏီ ဆက်သွယ်မှုများ"</string>
<string name="android_system_label" msgid="2797790869522345065">"မိုဘိုင်း ဝန်ဆောင်မှုပေးသူ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"မိုဘိုင်းဒေတာ ကုန်သွားပါပြီ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"သင်၏ မိုဘိုင်း ဒေတာကို ပိတ်ထားပါသည်"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ဥပမာ− ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှုမရှိခြင်း ဖြစ်နိုင်ပါသည်။"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"မည်သို့ပင်ဖြစ်စေ ဘရောက်ဇာမှတစ်ဆင့် ရှေ့ဆက်ရန်"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"စွမ်းဆောင်ရည် မြှင့်တင်အက်ပ်"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"သင်၏ မိုဘိုင်းဖုန်းကုမ္ပဏီထံမှ 5G ရွေးစရာများ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"သင့်အက်ပ်အသုံးပြုမှုအတွက် ရွေးစရာများကြည့်ရန် %s ၏ ဝဘ်ဆိုက်သို့ ဝင်ကြည့်ပါ"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ယခုမလုပ်ပါ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"စီမံရန်"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"စွမ်းဆောင်ရည် မြှင့်တင်အက်ပ် ဝယ်ယူရန်။"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ne/strings.xml b/packages/CarrierDefaultApp/res/values-ne/strings.xml
index 169ceff..9bf2fb1 100644
--- a/packages/CarrierDefaultApp/res/values-ne/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ne/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"सेवा प्रदायकसँग गरिएका कुराकानीहरू"</string>
<string name="android_system_label" msgid="2797790869522345065">"मोबाइलको सेवा प्रदायक छनौट गर्नुहोस्"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा सकियो"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"तपाईंको मोबाइल डेटा निष्क्रिय पारिएको छ"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"पर्फर्मेन्स बुस्ट"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"तपाईंको सेवा प्रदायकले उपलब्ध गराएका 5G सम्बन्धी विकल्पहरू"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"एप प्रयोग गर्दा अझ राम्रो सुविधा पाउन %s को वेबसाइटमा गई विकल्पहरू हेर्नुहोस्"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"अहिले होइन"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"व्यवस्थापन गर्नुहोस्"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"पर्फर्मेन्स बुस्ट किन्नुहोस्।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nl/strings.xml b/packages/CarrierDefaultApp/res/values-nl/strings.xml
index 35ecb3c..b2850c0 100644
--- a/packages/CarrierDefaultApp/res/values-nl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nl/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Berichten van provider"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobiele provider"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiele data verbruikt"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Je mobiele data zijn uitgeschakeld"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Toch doorgaan via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestatieboost"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-opties van je provider"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Ga naar de website van %s om opties voor de app-functionaliteit te zien"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Niet nu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Beheren"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Koop een prestatieboost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-or/strings.xml b/packages/CarrierDefaultApp/res/values-or/strings.xml
index dc13b65..884af9a 100644
--- a/packages/CarrierDefaultApp/res/values-or/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-or/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"କେରିଅର କମ୍ୟୁନିକେସନ୍ସ"</string>
<string name="android_system_label" msgid="2797790869522345065">"ମୋବାଇଲ୍ କେରିଅର୍"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ମୋବାଇଲ୍ ଡାଟା ଶେଷ ହୋଇଯାଇଛି"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ଆପଣଙ୍କ ମୋବାଇଲ୍ ଡାଟା ନିଷ୍କ୍ରୀୟ କରାଯାଇଛି"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ହୋଇନଥାଇପାରେ।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ବ୍ରାଉଜର୍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ପରଫରମାନ୍ସ ବୁଷ୍ଟ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"ଆପଣଙ୍କ କେରିଅରରୁ 5G ବିକଳ୍ପଗୁଡ଼ିକ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ଆପଣଙ୍କ ଆପ ଅନୁଭୂତି ପାଇଁ ବିକଳ୍ପ ଦେଖିବାକୁ %sର ୱେବସାଇଟକୁ ଭିଜିଟ କରନ୍ତୁ"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ଏକ ପରଫରମାନ୍ସ ବୁଷ୍ଟ କିଣନ୍ତୁ।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pl/strings.xml b/packages/CarrierDefaultApp/res/values-pl/strings.xml
index 3ca001b..3f499a7 100644
--- a/packages/CarrierDefaultApp/res/values-pl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pl/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Informacje od operatora"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operator komórkowy"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Osiągnięto limit komórkowej transmisji danych"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilna transmisja danych została wyłączona"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Kontynuuj mimo to w przeglądarce"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zwiększenie wydajności"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opcje 5G u Twojego operatora"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Opcje dotyczące korzystania z aplikacji znajdziesz na stronie firmy %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nie teraz"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Zarządzaj"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kup wzmocnienie wydajności"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
index cb8329c..cb3bca9 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicações da operadora"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operadora de celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Os dados móveis se esgotaram"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim pelo navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de performance"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opções 5G da sua operadora"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visite o site de %s para conferir opções da sua experiência no app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerenciar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar um aumento de performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
index 7e435cf..137a1c6 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicações do operador"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operador móvel"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Dados móveis esgotados"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os seus dados móveis foram desativados"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim através do navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento do desempenho"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opções 5G do seu operador"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visite o Website de %s para ver opções para a experiência da sua app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerir"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compre um aumento do desempenho."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt/strings.xml b/packages/CarrierDefaultApp/res/values-pt/strings.xml
index cb8329c..cb3bca9 100644
--- a/packages/CarrierDefaultApp/res/values-pt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicações da operadora"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operadora de celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Os dados móveis se esgotaram"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim pelo navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de performance"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opções 5G da sua operadora"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Visite o site de %s para conferir opções da sua experiência no app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerenciar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar um aumento de performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ro/strings.xml b/packages/CarrierDefaultApp/res/values-ro/strings.xml
index 042d9ec..78b910e 100644
--- a/packages/CarrierDefaultApp/res/values-ro/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ro/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Comunicări de la operator"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operator de telefonie mobilă"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Datele mobile au expirat"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Datele mobile au fost dezactivate"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuă oricum prin browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Boost de performanță"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opțiuni 5G de la operator"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Accesează site-ul %s ca să vezi opțiunile pentru experiența ta cu aplicațiile"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nu acum"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestionează"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achiziționează un boost de performanță."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ru/strings.xml b/packages/CarrierDefaultApp/res/values-ru/strings.xml
index 0c25796..936a6fa 100644
--- a/packages/CarrierDefaultApp/res/values-ru/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ru/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Оператор связи"</string>
<string name="android_system_label" msgid="2797790869522345065">"Оператор мобильной связи"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобильный трафик израсходован"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильный Интернет отключен"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Например, страница входа в аккаунт может быть фиктивной."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Продолжить в браузере"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Повышение производительности"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Сеть 5G от оператора связи"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Посетите сайт оператора (%s), чтобы узнать, как улучшить производительность приложения."</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сейчас"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Настроить"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Повысьте производительность сети за плату."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sk/strings.xml b/packages/CarrierDefaultApp/res/values-sk/strings.xml
index e14e087..77951cf 100644
--- a/packages/CarrierDefaultApp/res/values-sk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sk/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikácie s operátorom"</string>
<string name="android_system_label" msgid="2797790869522345065">"Poskytovateľ mobilných služieb"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilné dáta sa minuli"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Vaše mobilné dáta boli deaktivované"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Pokračovať pomocou prehliadača"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zvýšenie výkonu"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Možnosti siete 5G od vášho operátora"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Ak chcete zistiť, aké sú možnosti prostredia v aplikácii, prejdite na web %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Teraz nie"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Spravovať"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kúpte si zvýšenie výkonu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sl/strings.xml b/packages/CarrierDefaultApp/res/values-sl/strings.xml
index 21cb944..bee2217 100644
--- a/packages/CarrierDefaultApp/res/values-sl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sl/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Porabili ste vse mobilne podatke"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Prenos podatkov v mobilnih omrežjih je deaktiviran"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vseeno nadaljuj v brskalniku"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ojačevalnik zmogljivosti"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Operaterjeve možnosti 5G"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Obiščite spletno mesto %s, da si ogledate možnosti izkušnje aplikacije."</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne zdaj"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljanje"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite ojačevalnik zmogljivosti."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml
index 9d501d9..238921a 100644
--- a/packages/CarrierDefaultApp/res/values-sq/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Komunikimet e operatorit celular"</string>
<string name="android_system_label" msgid="2797790869522345065">"Operatori celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Të dhënat celulare kanë përfunduar"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Të dhënat celulare janë çaktivizuar"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Përforcimi i performancës"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Opsionet 5G nga operatori yt celular"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Vizito sajtin e uebit të %s për të parë opsione për përvojën tënde me aplikacionin"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Jo tani"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Menaxho"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Bli një paketë përforcimi të performancës."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sr/strings.xml b/packages/CarrierDefaultApp/res/values-sr/strings.xml
index 257d53b..c99431b 100644
--- a/packages/CarrierDefaultApp/res/values-sr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sr/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Обавештења мобилног оператера"</string>
<string name="android_system_label" msgid="2797790869522345065">"Мобилни оператер"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилни подаци су потрошени"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ипак настави преко прегледача"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Побољшање учинка"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G опције мобилног оператера"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Опције за доживљај апликације потражите на веб-сајту мобилног оператера %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сада"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управљај"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купите побољшање учинка."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sv/strings.xml b/packages/CarrierDefaultApp/res/values-sv/strings.xml
index 1886ed9..d2e8d93 100644
--- a/packages/CarrierDefaultApp/res/values-sv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sv/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Carrier Communications"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobiloperatör"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Slut på mobildata"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Din mobildata har inaktiverats"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Fortsätt ändå via webbläsaren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestandahöjning"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"5G-alternativ från operatören"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Se alternativ för appupplevelsen på webbplatsen för %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Inte nu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Hantera"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Köp en prestandahöjning."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index fc3450f..5dc7921 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Mawasiliano ya Mtoa Huduma"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mtoa Huduma za Simu"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data ya mtandao wa simu imekwisha"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Endelea hata hivyo kupitia kivinjari"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Kuongeza utendaji"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Chaguo za 5G kutoka kwa mtoa huduma wako"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Tembelea tovuti ya %s ili uone chaguo za hali ya matumizi ya programu yako"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Si sasa"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Dhibiti"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Nunua programu ya kuongeza utendaji."</string>
diff --git a/packages/CarrierDefaultApp/res/values-te/strings.xml b/packages/CarrierDefaultApp/res/values-te/strings.xml
index 944ee75..5f86828 100644
--- a/packages/CarrierDefaultApp/res/values-te/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-te/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"క్యారియర్ కమ్యూనికేషన్లు"</string>
<string name="android_system_label" msgid="2797790869522345065">"మొబైల్ క్యారియర్"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"మొబైల్ డేటాను పూర్తిగా ఉపయోగించారు"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"మీ మొబైల్ డేటా నిష్క్రియం చేయబడింది"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించండి"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"పనితీరు బూస్ట్"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"మీ క్యారియర్ నుండి 5G ఆప్షన్లు"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"మీ యాప్ అనుభవం కోసం ఆప్షన్లను చూడటానికి %s వెబ్సైట్కు వెళ్లండి"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ఇప్పుడు కాదు"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"మేనేజ్ చేయండి"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"పనితీరు బూస్ట్ను కొనుగోలు చేయండి."</string>
diff --git a/packages/CarrierDefaultApp/res/values-th/strings.xml b/packages/CarrierDefaultApp/res/values-th/strings.xml
index e13ce44..586ffd5 100644
--- a/packages/CarrierDefaultApp/res/values-th/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-th/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"การสื่อสารจากผู้ให้บริการ"</string>
<string name="android_system_label" msgid="2797790869522345065">"ผู้ให้บริการเครือข่ายมือถือ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"เน็ตมือถือหมดแล้ว"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"อินเทอร์เน็ตมือถือของคุณถูกปิดใช้งานแล้ว"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"การเพิ่มประสิทธิภาพ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"ตัวเลือก 5G จากผู้ให้บริการ"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"ดูตัวเลือกต่างๆ สำหรับประสบการณ์การใช้งานแอปได้ที่เว็บไซต์ของ %s"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ไว้ทีหลัง"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"จัดการ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ซื้อการเพิ่มประสิทธิภาพ"</string>
diff --git a/packages/CarrierDefaultApp/res/values-tl/strings.xml b/packages/CarrierDefaultApp/res/values-tl/strings.xml
index bdb09ac..a311a25 100644
--- a/packages/CarrierDefaultApp/res/values-tl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tl/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Mga Pakikipag-ugnayan sa Carrier"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Naubos na ang mobile data"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Na-deactivate na ang iyong mobile data"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Halimbawa, maaaring hindi pag-aari ng ipinapakitang organisasyon ang page ng login."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Pag-boost ng performance"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Mga opsyon sa 5G mula sa carrier mo"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Pumunta sa website ng %s para tingnan ang mga opsyon para sa iyong experience sa app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Huwag muna"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Pamahalaan"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Bumili ng pang-boost ng performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index ef2677f..0c7cdc5 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"کیریئر سے متعلق مواصلات"</string>
<string name="android_system_label" msgid="2797790869522345065">"موبائل کیریئر"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"موبائل ڈیٹا ختم ہو چکا ہے"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"آپ کا موبائل ڈیٹا غیر فعال کر دیا گیا ہے"</string>
@@ -16,8 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"پرفارمینس بوسٹ"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"آپ کے کیریئر سے 5G کے اختیارات"</string>
+ <!-- String.format failed for translation -->
<!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
<skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ابھی نہیں"</string>
diff --git a/packages/CarrierDefaultApp/res/values-uz/strings.xml b/packages/CarrierDefaultApp/res/values-uz/strings.xml
index dd48975..0f25e7e 100644
--- a/packages/CarrierDefaultApp/res/values-uz/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uz/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Operator aloqasi"</string>
<string name="android_system_label" msgid="2797790869522345065">"Mobil aloqa operatori"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobil internet tugab qoldi"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil internet o‘chirildi"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Brauzerda davom ettirish"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Unumdorlikni kuchaytirish"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Operatordan 5G aloqa parametrlari"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Ilovadan foydalanish usullarini koʻrish uchun %s saytini oching"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Hozir emas"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Boshqarish"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Unumdorlikni kuchaytirish xizmatini xarid qiling."</string>
diff --git a/packages/CarrierDefaultApp/res/values-vi/strings.xml b/packages/CarrierDefaultApp/res/values-vi/strings.xml
index b01f951..d99aa22 100644
--- a/packages/CarrierDefaultApp/res/values-vi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-vi/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Nhà cung cấp dịch vụ truyền thông"</string>
<string name="android_system_label" msgid="2797790869522345065">"Nhà cung cấp dịch vụ di động"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Dữ liệu di động đã hết"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Dữ liệu di động của bạn đã bị hủy kích hoạt"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Ví dụ: trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vẫn tiếp tục qua trình duyệt"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Tăng hiệu suất"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Tuỳ chọn 5G từ nhà mạng của bạn"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Truy cập trang web của %s để xem các lựa chọn cho trải nghiệm trên ứng dụng"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Để sau"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Quản lý"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Mua gói tăng hiệu suất."</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
index e06cddb..b05835d 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"运营商通信"</string>
<string name="android_system_label" msgid="2797790869522345065">"移动运营商"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"移动数据流量已用尽"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"您的移动数据网络已停用"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登录页面可能并不属于页面上显示的单位。"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"仍然通过浏览器继续操作"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"性能提升方案"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"您的运营商提供的 5G 选项"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"访问%s的网站可查看您的应用体验选项"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"以后再说"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"购买一份性能提升方案。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zu/strings.xml b/packages/CarrierDefaultApp/res/values-zu/strings.xml
index dc09c9d..e624a19 100644
--- a/packages/CarrierDefaultApp/res/values-zu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zu/strings.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_name (2809080280462257271) -->
- <skip />
+ <string name="app_name" msgid="2809080280462257271">"Inkampani Yezokuxhumana"</string>
<string name="android_system_label" msgid="2797790869522345065">"Inkampini yenethiwekhi yeselula"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Idatha yeselula iphelile"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Idatha yakho yeselula yenziwe yangasebenzi"</string>
@@ -16,10 +15,8 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Qhubeka noma kunjalo ngesiphequluli"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"I-boost yokusebenza"</string>
- <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
- <skip />
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_title" msgid="3126203390685781861">"Okukhethwa kukho kwe-5G okuvela kunkampani yakho yenethiwekhi"</string>
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"Vakashela iwebhusayithi ye-%s ukuze ubone okukhethwa kukho kolwazi lwakho lwe-app"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Hhayi manje"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Phatha"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Thenga i-boost yokusebenza."</string>
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml
new file mode 100644
index 0000000..aafe466
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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="M7,20H4Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20V6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18H7ZM9,20V18.2Q8.55,17.775 8.275,17.225Q8,16.675 8,16Q8,15.325 8.275,14.775Q8.55,14.225 9,13.8V12H13V13.8Q13.45,14.225 13.725,14.775Q14,15.325 14,16Q14,16.675 13.725,17.225Q13.45,17.775 13,18.2V20ZM11,17.5Q11.65,17.5 12.075,17.075Q12.5,16.65 12.5,16Q12.5,15.35 12.075,14.925Q11.65,14.5 11,14.5Q10.35,14.5 9.925,14.925Q9.5,15.35 9.5,16Q9.5,16.65 9.925,17.075Q10.35,17.5 11,17.5ZM21,20H16Q15.575,20 15.288,19.712Q15,19.425 15,19V10Q15,9.575 15.288,9.287Q15.575,9 16,9H21Q21.425,9 21.712,9.287Q22,9.575 22,10V19Q22,19.425 21.712,19.712Q21.425,20 21,20ZM17,18H20V11H17Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
index 97d201d..190e0a8 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="@android:color/system_neutral1_200">
+ android:tint="@android:color/system_accent1_200">
<path
android:fillColor="@android:color/white"
android:pathData="M6.85,15Q7.625,15 8.238,14.55Q8.85,14.1 9.1,13.375L9.475,12.225Q9.875,11.025 9.275,10.012Q8.675,9 7.55,9H4.025L4.5,12.925Q4.625,13.8 5.287,14.4Q5.95,15 6.85,15ZM17.15,15Q18.05,15 18.712,14.4Q19.375,13.8 19.5,12.925L19.975,9H16.475Q15.35,9 14.75,10.025Q14.15,11.05 14.55,12.25L14.9,13.375Q15.15,14.1 15.762,14.55Q16.375,15 17.15,15ZM6.85,17Q5.2,17 3.963,15.912Q2.725,14.825 2.525,13.175L2,9H1V7H7.55Q8.65,7 9.562,7.537Q10.475,8.075 11,9H13.025Q13.55,8.075 14.463,7.537Q15.375,7 16.475,7H23V9H22L21.475,13.175Q21.275,14.825 20.038,15.912Q18.8,17 17.15,17Q15.725,17 14.588,16.188Q13.45,15.375 13,14.025L12.625,12.9Q12.575,12.725 12.525,12.537Q12.475,12.35 12.425,12H11.575Q11.525,12.3 11.475,12.487Q11.425,12.675 11.375,12.85L11,14Q10.55,15.35 9.413,16.175Q8.275,17 6.85,17Z"/>
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
index 1611861..78120a3d 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
@@ -19,7 +19,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_200">
<path android:fillColor="@android:color/system_accent1_200"
android:pathData="M12,16.4 L7.6,12 12,7.6 16.4,12ZM13.4,21.375Q13.125,21.65 12.75,21.8Q12.375,21.95 12,21.95Q11.625,21.95 11.25,21.8Q10.875,21.65 10.6,21.375L2.625,13.4Q2.35,13.125 2.2,12.75Q2.05,12.375 2.05,12Q2.05,11.625 2.2,11.25Q2.35,10.875 2.625,10.6L10.575,2.65Q10.875,2.35 11.238,2.2Q11.6,2.05 12,2.05Q12.4,2.05 12.762,2.2Q13.125,2.35 13.425,2.65L21.375,10.6Q21.65,10.875 21.8,11.25Q21.95,11.625 21.95,12Q21.95,12.375 21.8,12.75Q21.65,13.125 21.375,13.4ZM12,19.2 L19.2,12Q19.2,12 19.2,12Q19.2,12 19.2,12L12,4.8Q12,4.8 12,4.8Q12,4.8 12,4.8L4.8,12Q4.8,12 4.8,12Q4.8,12 4.8,12L12,19.2Q12,19.2 12,19.2Q12,19.2 12,19.2Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml
new file mode 100644
index 0000000..f1fda17
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2023 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="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17ZM10.1,5.25Q11.075,4.975 12,4.975Q12.925,4.975 13.9,5.25L13.5,4H10.5ZM10.5,20H13.5L13.9,18.75Q12.925,19.025 12,19.025Q11.075,19.025 10.1,18.75ZM10.1,4H10.5H13.5H13.9Q12.925,4 12,4Q11.075,4 10.1,4ZM10.5,20H10.1Q11.075,20 12,20Q12.925,20 13.9,20H13.5Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
index 15f6987..dc12d12 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
@@ -19,7 +19,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="M7,20H4Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20V6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18H7ZM9,20V18.2Q8.55,17.775 8.275,17.225Q8,16.675 8,16Q8,15.325 8.275,14.775Q8.55,14.225 9,13.8V12H13V13.8Q13.45,14.225 13.725,14.775Q14,15.325 14,16Q14,16.675 13.725,17.225Q13.45,17.775 13,18.2V20ZM11,17.5Q11.65,17.5 12.075,17.075Q12.5,16.65 12.5,16Q12.5,15.35 12.075,14.925Q11.65,14.5 11,14.5Q10.35,14.5 9.925,14.925Q9.5,15.35 9.5,16Q9.5,16.65 9.925,17.075Q10.35,17.5 11,17.5ZM21,20H16Q15.575,20 15.288,19.712Q15,19.425 15,19V10Q15,9.575 15.288,9.287Q15.575,9 16,9H21Q21.425,9 21.712,9.287Q22,9.575 22,10V19Q22,19.425 21.712,19.712Q21.425,20 21,20ZM17,18H20V11H17Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml b/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml
index 9065520..0baf7ef 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_glasses.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.85,15Q7.625,15 8.238,14.55Q8.85,14.1 9.1,13.375L9.475,12.225Q9.875,11.025 9.275,10.012Q8.675,9 7.55,9H4.025L4.5,12.925Q4.625,13.8 5.287,14.4Q5.95,15 6.85,15ZM17.15,15Q18.05,15 18.712,14.4Q19.375,13.8 19.5,12.925L19.975,9H16.475Q15.35,9 14.75,10.025Q14.15,11.05 14.55,12.25L14.9,13.375Q15.15,14.1 15.762,14.55Q16.375,15 17.15,15ZM6.85,17Q5.2,17 3.963,15.912Q2.725,14.825 2.525,13.175L2,9H1V7H7.55Q8.65,7 9.562,7.537Q10.475,8.075 11,9H13.025Q13.55,8.075 14.463,7.537Q15.375,7 16.475,7H23V9H22L21.475,13.175Q21.275,14.825 20.038,15.912Q18.8,17 17.15,17Q15.725,17 14.588,16.188Q13.45,15.375 13,14.025L12.625,12.9Q12.575,12.725 12.525,12.537Q12.475,12.35 12.425,12H11.575Q11.525,12.3 11.475,12.487Q11.425,12.675 11.375,12.85L11,14Q10.55,15.35 9.413,16.175Q8.275,17 6.85,17Z"/>
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_watch.xml b/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
index d7a28d9..0f6b21f 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_watch.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="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17ZM10.1,5.25Q11.075,4.975 12,4.975Q12.925,4.975 13.9,5.25L13.5,4H10.5ZM10.5,20H13.5L13.9,18.75Q12.925,19.025 12,19.025Q11.075,19.025 10.1,18.75ZM10.1,4H10.5H13.5H13.9Q12.925,4 12,4Q11.075,4 10.1,4ZM10.5,20H10.1Q11.075,20 12,20Q12.925,20 13.9,20H13.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 d1d2c70..d470d4c 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -38,8 +38,7 @@
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_marginTop="18dp" />
<LinearLayout style="@style/Description">
<TextView
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index ac5294a..79f04b9 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -29,7 +29,6 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="24dp"
- android:tint="@android:color/system_accent1_600"
android:importantForAccessibility="no"
android:contentDescription="@null"/>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 99b776c..71ae578 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -39,6 +39,7 @@
import static com.android.companiondevicemanager.Utils.getApplicationLabel;
import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
import static com.android.companiondevicemanager.Utils.getIcon;
+import static com.android.companiondevicemanager.Utils.getImageColor;
import static com.android.companiondevicemanager.Utils.getVendorHeaderIcon;
import static com.android.companiondevicemanager.Utils.getVendorHeaderName;
import static com.android.companiondevicemanager.Utils.hasVendorIcon;
@@ -56,7 +57,6 @@
import android.companion.IAssociationRequestCallback;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.res.Configuration;
import android.graphics.BlendMode;
import android.graphics.BlendModeColorFilter;
import android.graphics.Color;
@@ -463,8 +463,6 @@
final Drawable vendorIcon;
final CharSequence vendorName;
final Spanned title;
- int nightModeFlags = getResources().getConfiguration().uiMode
- & Configuration.UI_MODE_NIGHT_MASK;
if (!SUPPORTED_SELF_MANAGED_PROFILES.contains(deviceProfile)) {
throw new RuntimeException("Unsupported profile " + deviceProfile);
@@ -477,8 +475,7 @@
vendorName = getVendorHeaderName(this, packageName, userId);
mVendorHeaderImage.setImageDrawable(vendorIcon);
if (hasVendorIcon(this, packageName, userId)) {
- int color = nightModeFlags == Configuration.UI_MODE_NIGHT_YES
- ? android.R.color.system_accent1_200 : android.R.color.system_accent1_600;
+ int color = getImageColor(this);
mVendorHeaderImage.setColorFilter(getResources().getColor(color, /* Theme= */null));
}
} catch (PackageManager.NameNotFoundException e) {
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index 328c67e..d8348d1 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -17,6 +17,7 @@
package com.android.companiondevicemanager;
import static com.android.companiondevicemanager.Utils.getIcon;
+import static com.android.companiondevicemanager.Utils.getImageColor;
import android.content.Context;
import android.view.LayoutInflater;
@@ -65,6 +66,10 @@
viewHolder.mImageView.setImageDrawable(
getIcon(mContext, android.R.drawable.stat_sys_data_bluetooth));
}
+
+ viewHolder.mImageView.setColorFilter(
+ mContext.getResources().getColor(getImageColor(mContext), /* Theme= */null));
+
return viewHolder;
}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
index fceca91..8c14f80 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
@@ -22,6 +22,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -120,6 +121,20 @@
}
}
+ private static boolean isDarkTheme(@NonNull Context context) {
+ int nightModeFlags = context.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
+ return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
+ }
+
+ // Get image color for the corresponding theme.
+ static int getImageColor(@NonNull Context context) {
+ if (isDarkTheme(context)) {
+ return android.R.color.system_accent1_200;
+ } else {
+ return android.R.color.system_accent1_600;
+ }
+ }
/**
* Getting ApplicationInfo from meta-data.
*/
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index f655d6b..1d069b6 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -129,4 +129,6 @@
<string name="get_dialog_heading_from_another_device">From another device</string>
<!-- This is a label for a button that takes the user to other available devices. [CHAR LIMIT=120] -->
<string name="get_dialog_option_headline_use_a_different_device">Use a different device</string>
+ <!-- Text shown on a snackbar when the app cancelled the UI. [CHAR LIMIT=120] -->
+ <string name="request_cancelled_by">Request cancelled by <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index e8e3974..5d72424 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -38,7 +38,9 @@
import com.android.credentialmanager.createflow.CreateCredentialScreen
import com.android.credentialmanager.createflow.hasContentToDisplay
import com.android.credentialmanager.getflow.GetCredentialScreen
+import com.android.credentialmanager.getflow.GetGenericCredentialScreen
import com.android.credentialmanager.getflow.hasContentToDisplay
+import com.android.credentialmanager.getflow.isFallbackScreen
import com.android.credentialmanager.ui.theme.PlatformTheme
@ExperimentalMaterialApi
@@ -118,11 +120,19 @@
providerActivityLauncher = launcher
)
} else if (getCredentialUiState != null && hasContentToDisplay(getCredentialUiState)) {
- GetCredentialScreen(
- viewModel = viewModel,
- getCredentialUiState = getCredentialUiState,
- providerActivityLauncher = launcher
- )
+ if (isFallbackScreen(getCredentialUiState)) {
+ GetGenericCredentialScreen(
+ viewModel = viewModel,
+ getCredentialUiState = getCredentialUiState,
+ providerActivityLauncher = launcher
+ )
+ } else {
+ GetCredentialScreen(
+ viewModel = viewModel,
+ getCredentialUiState = getCredentialUiState,
+ providerActivityLauncher = launcher
+ )
+ }
} else {
Log.d(Constants.LOG_TAG, "UI wasn't able to render neither get nor create flow")
reportInstantiationErrorAndFinishActivity(credManRepo)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index b5c8989..bd0b4cc 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -29,7 +29,6 @@
import android.credentials.ui.GetCredentialProviderData
import android.credentials.ui.RequestInfo
import android.graphics.drawable.Drawable
-import android.service.credentials.CredentialEntry
import android.text.TextUtils
import android.util.Log
import com.android.credentialmanager.common.Constants
@@ -57,6 +56,7 @@
import androidx.credentials.provider.Action
import androidx.credentials.provider.AuthenticationAction
import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.CredentialEntry
import androidx.credentials.provider.CustomCredentialEntry
import androidx.credentials.provider.PasswordCredentialEntry
import androidx.credentials.provider.PublicKeyCredentialEntry
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
index 26aadd9..1f99500 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
@@ -84,7 +84,7 @@
return Entry(
key,
subkey,
- RemoteEntry(pendingIntent).slice
+ RemoteEntry.toSlice(RemoteEntry(pendingIntent))
)
}
@@ -219,12 +219,16 @@
key,
subkey,
CreateEntry.toSlice(
- providerUserDisplayName,
- null,
- footerDescription,
- lastUsedTime,
- credCountMap,
- pendingIntent
+ CreateEntry(
+ accountName = providerUserDisplayName,
+ pendingIntent = pendingIntent,
+ description = footerDescription,
+ lastUsedTime = lastUsedTime,
+ icon = null,
+ passwordCredentialCount = passwordCount,
+ publicKeyCredentialCount = passkeyCount,
+ totalCredentialCount = totalCredentialCount,
+ )
),
Intent()
)
@@ -241,7 +245,7 @@
return Entry(
key,
subkey,
- RemoteEntry(pendingIntent).slice
+ RemoteEntry.toSlice(RemoteEntry(pendingIntent))
)
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index bcf692f..7b98049 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -16,6 +16,7 @@
package com.android.credentialmanager.createflow
+import android.text.TextUtils
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.result.ActivityResult
import androidx.activity.result.IntentSenderRequest
@@ -668,7 +669,7 @@
entryHeadlineText = requestDisplayInfo.title,
entrySecondLineText = when (requestDisplayInfo.type) {
CredentialType.PASSKEY -> {
- if (requestDisplayInfo.subtitle != null) {
+ if (!TextUtils.isEmpty(requestDisplayInfo.subtitle)) {
requestDisplayInfo.subtitle + " • " + stringResource(
R.string.passkey_before_subtitle
)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index 5632458..c27ac94 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -59,6 +59,8 @@
import com.android.credentialmanager.common.ui.SnackbarActionText
import com.android.credentialmanager.common.ui.HeadlineText
import com.android.credentialmanager.common.ui.CredentialListSectionHeader
+import com.android.credentialmanager.common.ui.HeadlineIcon
+import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
import com.android.credentialmanager.common.ui.Snackbar
import com.android.credentialmanager.common.ui.setTransparentSystemBarsColor
import com.android.credentialmanager.common.ui.setBottomSheetSystemBarsColor
@@ -167,22 +169,42 @@
providerDisplayInfo.sortedUserNameToCredentialEntryList
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
SheetContainerCard {
+ // When only one provider (not counting the remote-only provider) exists, display that
+ // provider's icon + name up top.
+ if (providerInfoList.size <= 2) { // It's only possible to be the single provider case
+ // if we are started with no more than 2 providers.
+ val nonRemoteProviderList = providerInfoList.filter(
+ { it.credentialEntryList.isNotEmpty() || it.authenticationEntryList.isNotEmpty() }
+ )
+ if (nonRemoteProviderList.size == 1) {
+ val providerInfo = nonRemoteProviderList.firstOrNull() // First should always work
+ // but just to be safe.
+ if (providerInfo != null) {
+ item {
+ HeadlineIcon(
+ bitmap = providerInfo.icon.toBitmap().asImageBitmap(),
+ tint = Color.Unspecified,
+ )
+ }
+ item { Divider(thickness = 4.dp, color = Color.Transparent) }
+ item { LargeLabelTextOnSurfaceVariant(text = providerInfo.displayName) }
+ item { Divider(thickness = 16.dp, color = Color.Transparent) }
+ }
+ }
+ }
+
+ val hasSingleEntry = (sortedUserNameToCredentialEntryList.size == 1 &&
+ authenticationEntryList.isEmpty()) || (sortedUserNameToCredentialEntryList.isEmpty() &&
+ authenticationEntryList.size == 1)
item {
HeadlineText(
text = stringResource(
- if (sortedUserNameToCredentialEntryList
- .size == 1 && authenticationEntryList.isEmpty()
- ) {
- if (sortedUserNameToCredentialEntryList.first()
- .sortedCredentialEntryList.first().credentialType
+ if (hasSingleEntry) {
+ if (sortedUserNameToCredentialEntryList.firstOrNull()
+ ?.sortedCredentialEntryList?.first()?.credentialType
== CredentialType.PASSKEY
) R.string.get_dialog_title_use_passkey_for
else R.string.get_dialog_title_use_sign_in_for
- } else if (
- sortedUserNameToCredentialEntryList
- .isEmpty() && authenticationEntryList.size == 1
- ) {
- R.string.get_dialog_title_use_sign_in_for
} else R.string.get_dialog_title_choose_sign_in_for,
requestDisplayInfo.appName
),
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetGenericCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetGenericCredentialComponents.kt
new file mode 100644
index 0000000..8b95b5e
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetGenericCredentialComponents.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.credentialmanager.getflow
+
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
+import androidx.compose.runtime.Composable
+import com.android.credentialmanager.CredentialSelectorViewModel
+
+@Composable
+fun GetGenericCredentialScreen(
+ viewModel: CredentialSelectorViewModel,
+ getCredentialUiState: GetCredentialUiState,
+ providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
+) {
+ // TODO(b/274129098): Implement Screen for mDocs
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 263a632..7a86790 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -41,6 +41,10 @@
!state.requestDisplayInfo.preferImmediatelyAvailableCredentials)
}
+internal fun isFallbackScreen(state: GetCredentialUiState): Boolean {
+ return false
+}
+
internal fun findAutoSelectEntry(providerDisplayInfo: ProviderDisplayInfo): CredentialEntryInfo? {
if (providerDisplayInfo.authenticationEntryList.isNotEmpty()) {
return null
diff --git a/packages/CtsShim/Android.bp b/packages/CtsShim/Android.bp
index 31cd760..baafe7b 100644
--- a/packages/CtsShim/Android.bp
+++ b/packages/CtsShim/Android.bp
@@ -44,6 +44,9 @@
arm64: {
apk: "apk/arm/CtsShimPriv.apk",
},
+ riscv64: {
+ apk: "apk/riscv64/CtsShimPriv.apk",
+ },
x86: {
apk: "apk/x86/CtsShimPriv.apk",
},
@@ -82,6 +85,9 @@
arm64: {
apk: "apk/arm/CtsShim.apk",
},
+ riscv64: {
+ apk: "apk/riscv64/CtsShim.apk",
+ },
x86: {
apk: "apk/x86/CtsShim.apk",
},
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index fb09286..af306a5 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index 07915ce..98c5351 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/riscv64/CtsShim.apk b/packages/CtsShim/apk/riscv64/CtsShim.apk
new file mode 100644
index 0000000..af306a5
--- /dev/null
+++ b/packages/CtsShim/apk/riscv64/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/riscv64/CtsShimPriv.apk b/packages/CtsShim/apk/riscv64/CtsShimPriv.apk
new file mode 100644
index 0000000..9a9997d
--- /dev/null
+++ b/packages/CtsShim/apk/riscv64/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index fb09286..af306a5 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 20e94b6..29ad478 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index 72fb5d6..5f0e3c2 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Program geïnstalleer."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Wil jy hierdie program installeer?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Wil jy hierdie program opdateer?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Program nie geïnstalleer nie."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Die installering van die pakket is geblokkeer."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Hierdie gebruiker kan nie onbekende programme installeer nie"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Hierdie gebruiker word nie toegelaat om programme te installeer nie"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Bestuur programme"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Geen spasie oor nie"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie geïnstalleer word nie. Maak spasie beskikbaar en probeer weer."</string>
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index 378770d..e2a25b3 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"መተግበሪያ ተጭኗል።"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ይህን መተግበሪያ መጫን ይፈልጋሉ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ይህን መተግበሪያ ማዘመን ይፈልጋሉ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"መተግበሪያ አልተጫነም።"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ያልታወቁ መተግበሪያዎች በዚህ ተጠቃሚ ሊጫኑ አይችሉም"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ይህ ተጠቃሚ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም"</string>
<string name="ok" msgid="7871959885003339302">"እሺ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"መተግበሪያዎችን ያቀናብሩ"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ቦታ ሞልቷል"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን መጫን አልቻለም። የተወሰነ ቦታ ያስለቅቁና እንደገና ይሞክሩ።"</string>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index f9df296..5c974b0 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"تم تثبيت التطبيق."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"هل تريد تثبيت هذا التطبيق؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"هل تريد تحديث هذا التطبيق؟"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"التطبيق ليس مثبتًا."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"تم حظر تثبيت الحزمة."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"يتعذر على هذا المستخدم تثبيت التطبيقات غير المعروفة"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"غير مسموح لهذا المستخدم بتثبيت التطبيقات"</string>
<string name="ok" msgid="7871959885003339302">"حسنًا"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"إدارة التطبيقات"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"نفدت مساحة التخزين"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> الرجاء تحرير بعض المساحة والمحاولة مرة أخرى."</string>
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
index 2b41b1e..5997f2d 100644
--- a/packages/PackageInstaller/res/values-as/strings.xml
+++ b/packages/PackageInstaller/res/values-as/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"এপ্ ইনষ্টল কৰা হ’ল।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"আপুনি এই এপ্টো ইনষ্টল কৰিবলৈ বিচাৰেনে?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"আপুনি এই এপ্টো আপডে’ট কৰিবলৈ বিচাৰেনে?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"এপ্ ইনষ্টল কৰা হোৱা নাই।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"পেকেজটোৰ ইনষ্টল অৱৰোধ কৰা হৈছে।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"এপ্টো ইনষ্টল কৰিব পৰা নগ\'ল কাৰণ ইয়াৰ সৈতে আগৰে পৰা থকা এটা পেকেজৰ সংঘাত হৈছে।"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"এই ব্যৱহাৰকাৰীয়ে অজ্ঞাত উৎসৰপৰা পোৱা এপসমূহ ইনষ্টল কৰিব নোৱাৰে"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"এই ব্যৱহাৰকাৰীজনৰ এপ্ ইনষ্টল কৰাৰ অনুমতি নাই"</string>
<string name="ok" msgid="7871959885003339302">"ঠিক আছে"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"এপ্ পৰিচালনা"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"খালী ঠাই নাই"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ইনষ্টল কৰিব পৰা নগ\'ল। কিছু খালী ঠাই উলিয়াই আকৌ চেষ্টা কৰক৷"</string>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index 9e915e3..0fb5005 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Tətbiq quraşdırılıb."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bu tətbiqi quraşdırmaq istəyirsiniz?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bu tətbiqi güncəlləmək istəyirsiniz?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Tətbiq quraşdırılmayıb."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin quraşdırılması blok edildi."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Bu paketin mövcud paket ilə ziddiyətinə görə tətbiq quraşdırılmadı."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Naməlum tətbiqlər bu istifadəçi tərəfindən quraşdırıla bilməz"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu istifadəçinin tətbiqi quraşdırmaq üçün icazəsi yoxdur"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Tətbiqi idarə edin"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Boş yer yoxdur"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> quraşdırıla bilməz. Yaddaş üçün yer boşaldıb yenidən təkrar edin."</string>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index 0a81ac6..f89266c 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Želite da instalirate ovu aplikaciju?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Želite da ažurirate ovu aplikaciju?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa je blokirano."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
<string name="ok" msgid="7871959885003339302">"Potvrdi"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Upravljajte apl."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema više prostora"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor i probajte ponovo."</string>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index e828c3c..369a60c 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Праграма ўсталявана."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Усталяваць гэту праграму?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Абнавіць гэту праграму?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Праграма не ўсталявана."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Усталяванне пакета заблакіравана."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Гэты карыстальнік не можа ўсталёўваць невядомыя праграмы"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Гэты карыстальнік не можа ўсталёўваць праграмы"</string>
<string name="ok" msgid="7871959885003339302">"ОК"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Кіраваць"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Не хапае месца"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Не ўдалося ўсталяваць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Вызваліце месца і паўтарыце спробу."</string>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index 110860b..8263fe1 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Приложението бе инсталирано."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Искате ли да инсталирате това приложение?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Искате ли да актуализирате това приложение?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Приложението не бе инсталирано."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирането на пакета бе блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Този потребител не може да инсталира неизвестни приложения"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Този потребител няма разрешение да инсталира приложения"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Прил.: Управл."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Няма място"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира. Освободете място и опитайте отново."</string>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index e7aed0b..0d15a7e 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"অ্যাপটি ইনস্টল করা হয়ে গেছে।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"আপনি কি এই অ্যাপটি ইনস্টল করতে চান?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"আপনি কি এই অ্যাপটি আপডেট করতে চান?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"অ্যাপটি ইনস্টল করা হয়নি।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ইনস্টল হওয়া থেকে প্যাকেজটিকে ব্লক করা হয়েছে।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"আগে থেকেই থাকা একটি প্যাকেজের সাথে প্যাকেজটির সমস্যা সৃষ্টি হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"এই ব্যবহারকারী অজানা অ্যাপ ইনস্টল করতে পারেন না"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"এই ব্যবহারকারীর অ্যাপ ইনস্টল করার অনুমতি নেই"</string>
<string name="ok" msgid="7871959885003339302">"ঠিক আছে"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"অ্যাপ পরিচালনা"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"জায়গা খালি নেই"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ইনস্টল করা যায়নি। কিছু পরিমাণ জায়গা খালি করে আবার চেষ্টা করুন।"</string>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index 10ed009..8b19769 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje ovog paketa je blokirano."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno instaliranje aplikacija"</string>
<string name="ok" msgid="7871959885003339302">"Uredu"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Uprav. aplik."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatak prostora"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ne možete instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor u pohrani i pokušajte ponovo."</string>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 337e6d9..d025b9a 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"S\'ha instal·lat l\'aplicació."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vols instal·lar aquesta aplicació?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vols actualitzar aquesta aplicació?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"No s\'ha instal·lat l\'aplicació."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aquest usuari no pot instal·lar aplicacions desconegudes"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Aquest usuari no té permís per instal·lar aplicacions"</string>
<string name="ok" msgid="7871959885003339302">"D\'acord"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gestiona apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espai esgotat"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g>. Allibera espai i torna-ho a provar."</string>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 33ec41c1..5799e72 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Chcete tuto aplikaci nainstalovat?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete tuto aplikaci aktualizovat?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikaci nelze nainstalovat."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalace balíčku byla zablokována."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tento uživatel nemůže instalovat neznámé aplikace"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tento uživatel nesmí instalovat aplikace"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Správa aplikací"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatek místa"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze nainstalovat. Uvolněte místo v paměti a zkuste to znovu."</string>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 657eccb..d312de2 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Appen er installeret."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du opdatere denne app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Appen blev ikke installeret."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakken blev forhindret i at blive installeret."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Denne bruger kan ikke installere ukendte apps"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Denne bruger har ikke tilladelse til at installere apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Administrer apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Der er ikke mere plads"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigør noget plads, og prøv igen."</string>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 66e1e59c..1332c94 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App wurde installiert."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Möchtest du diese App installieren?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Möchtest du diese App aktualisieren?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App wurde nicht installiert."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Die Installation des Pakets wurde blockiert."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Dieser Nutzer darf keine unbekannten Apps installieren"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Dieser Nutzer darf keine Apps installieren"</string>
<string name="ok" msgid="7871959885003339302">"Ok"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Apps verwalten"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kein freier Speicher vorhanden"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht installiert werden. Gib Speicherplatz frei und versuche es noch einmal."</string>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index ec0cfc7..8b092d7 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Η εφαρμογή εγκαταστάθηκε."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή;"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Θέλετε να ενημερώσετε αυτήν την εφαρμογή;"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Η εφαρμογή δεν εγκαταστάθηκε."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή το πακέτο είναι σε διένεξη με κάποιο υπάρχον πακέτο."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Δεν είναι δυνατή η εγκατάσταση άγνωστων εφαρμογών από αυτόν τον χρήστη"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Δεν επιτρέπεται η εγκατάσταση εφαρμογών σε αυτόν τον χρήστη"</string>
<string name="ok" msgid="7871959885003339302">"ΟΚ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Διαχ. εφαρμογών"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Δεν υπάρχει χώρος"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>. Απελευθερώστε λίγο χώρο και προσπαθήστε ξανά."</string>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index b718868..bb05ec4 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index 03f24c9..f2457f2 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -26,6 +26,7 @@
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
+ <string name="install_confirm_question_update_owner_reminder" msgid="3750986542284587290">"Update this app from <xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>?\n\nThis app normally receives updates from <xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>. By updating from a different source, you may receive future updates from any source on your phone. App functionality may change."</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -41,6 +42,7 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <string name="update_anyway" msgid="8792432341346261969">"Update anyway"</string>
<string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index b718868..bb05ec4 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index b718868..bb05ec4 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index a095216..a674c20 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -26,6 +26,7 @@
<string name="install_done" msgid="5987363587661783896">"App installed."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
+ <string name="install_confirm_question_update_owner_reminder" msgid="3750986542284587290">"Update this app from <xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>?\n\nThis app normally receives updates from <xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>. By updating from a different source, you may receive future updates from any source on your phone. App functionality may change."</string>
<string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
@@ -41,6 +42,7 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <string name="update_anyway" msgid="8792432341346261969">"Update anyway"</string>
<string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 1d7b8c1..12812ae 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Se instaló la app."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"¿Deseas instalar esta app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"¿Deseas actualizar esta app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"No se instaló la app."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Se bloqueó el paquete para impedir la instalación."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"No se instaló la app debido a un conflicto con un paquete."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario no puede instalar apps desconocidas"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario no puede instalar apps"</string>
<string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gestionar apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sin espacio"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index 482ccf6..b6714d3 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplicación instalada."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"¿Quieres instalar esta aplicación?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"¿Quieres actualizar esta aplicación?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"No se ha instalado la aplicación."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Se ha bloqueado la instalación del paquete."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"La aplicación no se ha instalado debido a un conflicto con un paquete."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario no puede instalar aplicaciones desconocidas"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario no tiene permiso para instalar aplicaciones"</string>
<string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gestionar aplicaciones"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sin espacio"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index d5b5316..c4a3d05 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Rakendus on installitud."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Kas soovite selle rakenduse installida?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Kas soovite seda rakendust värskendada?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Rakendus pole installitud."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketi installimine blokeeriti."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"See kasutaja ei saa installida tundmatuid rakendusi"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Kasutajal ei ole lubatud rakendusi installida"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Rakend. haldam."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Pole ruumi"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud installida. Vabastage ruumi ja proovige uuesti."</string>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index 2ca4397..97339dc 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Instalatu da aplikazioa."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Aplikazioa instalatu nahi duzu?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Aplikazioa eguneratu nahi duzu?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Ez da instalatu aplikazioa."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketea instalatzeko aukera blokeatu egin da."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Erabiltzaile honek ezin ditu instalatu aplikazio ezezagunak"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Erabiltzaile honek ez du baimenik aplikazioak instalatzeko"</string>
<string name="ok" msgid="7871959885003339302">"Ados"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Kudeatu aplikazioak"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Ez dago behar adina toki"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g>. Egin toki pixka bat eta saiatu berriro."</string>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index e9775ce..65b3241 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"برنامه نصب شد."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"میخواهید این برنامه را نصب کنید؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"میخواهید این برنامه را بهروزرسانی کنید؟"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"برنامه نصب نشد."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"از نصب شدن بسته جلوگیری شد."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"این کاربر نمیتواند برنامههای ناشناس نصب کند"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"این کاربر مجاز به نصب برنامه نیست"</string>
<string name="ok" msgid="7871959885003339302">"بسیار خوب"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"مدیریت برنامهها"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"فضا کافی نیست"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> نصب نمیشود. مقداری از فضا را آزاد و دوباره امتحان کنید."</string>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index 058633b..a4306ae 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Sovellus on asennettu."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Haluatko asentaa tämän sovelluksen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Haluatko päivittää tämän sovelluksen?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Sovellusta ei asennettu."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin asennus estettiin."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tämä käyttäjä ei voi asentaa tuntemattomia sovelluksia."</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tämä käyttäjä ei voi asentaa sovelluksia."</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Sovellusvalinnat"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Tallennustila ei riitä"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen epäonnistui. Vapauta tallennustilaa ja yritä uudelleen."</string>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 2c5a04d..24efdd7 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Application installée."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette application?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette application?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gérer les applis"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espace insuffisant"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index 032499d..f3afb90 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Application installée."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette appli ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette appli ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du package a été bloquée."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le package est en conflit avec un package déjà présent."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gérer applis"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Mémoire insuffisante"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace et réessayer."</string>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index 6a37d7b..5763bf1 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Instalouse a aplicación."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Queres instalar esta aplicación?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Queres actualizar esta aplicación?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Non se instalou a aplicación"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Bloqueouse a instalación do paquete."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete que xa hai."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario non pode instalar aplicacións descoñecidas"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario non ten permiso para instalar aplicacións"</string>
<string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Xestionar apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Esgotouse o espazo"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espazo e téntao de novo."</string>
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
index 863c1aa..b3160e2 100644
--- a/packages/PackageInstaller/res/values-gu/strings.xml
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"શું તમે આ ઍપ ઇન્સ્ટૉલ કરવા માગો છો?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"શું તમે આ ઍપ અપડેટ કરવા માગો છો?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી નથી."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"પૅકેજને ઇન્સ્ટૉલ થવાથી બ્લૉક કરવામાં આવ્યું હતું."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"પૅકેજનો અસ્તિત્વમાંના પૅકેજ સાથે વિરોધાભાસ હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"આ વપરાશકર્તા અજાણી ઍપ્લિકેશનોને ઇન્સ્ટૉલ કરી શકતા નથી"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"આ વપરાશકર્તાને ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી"</string>
<string name="ok" msgid="7871959885003339302">"ઓકે"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ઍપને મેનેજ કરો"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"સ્પેસ નથી"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટૉલ કરી શકાઈ નથી. થોડું સ્પેસ ખાલી કરો અને ફરીથી પ્રયાસ કરો."</string>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 3339d35..63ee837 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ऐप्लिकेशन इंस्टॉल हो गया."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"क्या आपको यह ऐप्लिकेशन इंस्टॉल करना है?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"क्या आप इस ऐप्लिकेशन को अपडेट करना चाहते हैं?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ऐप्लिकेशन इंस्टॉल नहीं हुआ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"पैकेज को इंस्टॉल होने से ब्लॉक किया हुआ है."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"यह उपयोगकर्ता अनजान ऐप्लिकेशन इंस्टॉल नहीं कर सकता"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"इस उपयोगकर्ता को ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है"</string>
<string name="ok" msgid="7871959885003339302">"ठीक है"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ऐप्लिकेशन प्रबंधित करें"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"जगह नहीं है"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> को इंस्टॉल नहीं किया जा सका. थोड़ी जगह खाली करें और फिर से कोशिश करें."</string>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index 88fdbb77..2372754 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa blokirano je."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovaj korisnik nema dopuštenje za instaliranje aplikacija"</string>
<string name="ok" msgid="7871959885003339302">"U redu"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Upravljanje apl."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema dovoljno mjesta"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati. Oslobodite dio prostora i pokušajte ponovo."</string>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index db085ca..0ede377 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Alkalmazás telepítve."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Telepíti ezt az alkalmazást?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Frissíti ezt az alkalmazást?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Az alkalmazás nincs telepítve."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A csomag telepítését letiltotta a rendszer."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ez a felhasználó nem telepíthet ismeretlen alkalmazásokat"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ez a felhasználó nem telepíthet alkalmazásokat"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Alkalmazáskezelés"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nincs elég hely"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazást nem lehet telepíteni. Szabadítson fel egy kis helyet, és próbálkozzon újra."</string>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index 09be03a..ccf1ee4 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Հավելվածը տեղադրված է:"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Տեղադրե՞լ այս հավելվածը:"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Թարմացնե՞լ այս հավելվածը։"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Հավելվածը տեղադրված չէ:"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Այս օգտատերը չի կարող անհայտ հավելվածներ տեղադրել"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Այս օգտատիրոջը չի թույլատրվում տեղադրել հավելվածներ"</string>
<string name="ok" msgid="7871959885003339302">"Եղավ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Կառավարել հավելվածները"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Բավարար տարածք չկա"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Չհաջողվեց տեղադրել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը: Ազատեք տարածք և նորից փորձեք:"</string>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index ed6d23f..0e4d700 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikasi terinstal."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ingin menginstal aplikasi ini?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ingin mengupdate aplikasi ini?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak terinstal."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paket diblokir sehingga tidak dapat diinstal."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikasi tidak diinstal karena paket ini bentrok dengan paket yang sudah ada."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplikasi yang tidak dikenal tidak dapat diinstal oleh pengguna ini"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Pengguna ini tidak diizinkan menginstal aplikasi"</string>
<string name="ok" msgid="7871959885003339302">"Oke"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Kelola aplikasi"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kehabisan ruang penyimpanan"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat diinstal. Kosongkan sebagian ruang dan coba lagi."</string>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index 1da54cb..64086c8 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Forritið er uppsett."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Viltu setja upp þetta forrit?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Viltu uppfæra þetta forrit?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Forritið er ekki uppsett."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Lokað var á uppsetningu pakkans."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Þessi notandi getur ekki sett upp óþekkt forrit"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Þessi notandi hefur ekki leyfi til að setja upp forrit"</string>
<string name="ok" msgid="7871959885003339302">"Í lagi"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Stj. forritum"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Ekkert pláss eftir"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp. Losaðu um pláss og reyndu aftur."</string>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index c288d96..617bfda 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App installata."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vuoi installare questa app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vuoi aggiornare questa app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App non installata."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"È stata bloccata l\'installazione del pacchetto."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Questo utente non può installare app sconosciute"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"L\'utente non è autorizzato a installare app"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gestisci app"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Spazio esaurito"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index e3893d2..2261218 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"האפליקציה הותקנה."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"האם ברצונך להתקין אפליקציה זו?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"האם ברצונך לעדכן אפליקציה זו?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"האפליקציה לא הותקנה."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"החבילה נחסמה להתקנה."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"למשתמש הזה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"למשתמש הזה אין הרשאה להתקין אפליקציות"</string>
<string name="ok" msgid="7871959885003339302">"אישור"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ניהול אפליקציות"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"אין מספיק מקום"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g>. יש לפנות מקום אחסון ולנסות שוב."</string>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index 62149d1..9764f1b 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"アプリをインストールしました。"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"このアプリをインストールしますか?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"このアプリを更新しますか?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"アプリはインストールされていません。"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"パッケージのインストールはブロックされています。"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"パッケージが既存のパッケージと競合するため、アプリをインストールできませんでした。"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"このユーザーは不明なアプリをインストールできません"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"このユーザーはアプリをインストールできません"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"アプリの管理"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"容量不足"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> をインストールできませんでした。空き容量を増やしてもう一度お試しください。"</string>
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
index 507a262..ee0cefa 100644
--- a/packages/PackageInstaller/res/values-ka/strings.xml
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"აპი დაინსტალირებულია."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"გნებავთ ამ აპის დაყენება?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"გსურთ ამ აპის განახლება?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"აპი დაუინსტალირებელია."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ამ პაკეტის ინსტალაცია დაბლოკილია."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"აპი ვერ დაინსტალირდა, რადგან პაკეტი კონფლიქტშია არსებულ პაკეტთან."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ამ მომხმარებელს არ შეუძლია უცნობი აპების ინსტალაცია"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ამ მომხმარებელს არ აქვს აპების ინსტალაციის უფლება"</string>
<string name="ok" msgid="7871959885003339302">"კარგი"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"აპების მართვა"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"მეხსიერება არასაკმარისია"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ვერ დაინსტალირდა. გაათავისუფლეთ მეხსიერება და ცადეთ ხელახლა."</string>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index 6e11f2a..27b0289 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Қолданба орнатылды."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Бұл қолданбаны орнатқыңыз келе ме?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Бұл қолданбаны жаңартқыңыз келе ме?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Қолданба орнатылмады."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Пакетті орнатуға тыйым салынды."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Жаңа пакет пен бұрыннан бар пакеттің арасында қайшылық туындағандықтан, қолданба орнатылмады."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Бұл пайдаланушы белгісіз қолданбаларды орната алмайды"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Бұл пайдаланушының қолданбаларды орнату рұқсаты жоқ"</string>
<string name="ok" msgid="7871959885003339302">"Жарайды"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Қолданбаларды басқару"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Орын жоқ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы орнатылмады. Орын босатып, қайталап көріңіз."</string>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index d744ff7..1262181 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"បានដំឡើងកម្មវិធី។"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"តើអ្នកចង់ដំឡើងកម្មវិធីនេះដែរទេ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"តើអ្នកចង់ដំឡើងកំណែកម្មវិធីនេះដែរទេ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"មិនបានដំឡើងកម្មវិធីទេ។"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"កញ្ចប់ត្រូវបានទប់ស្កាត់មិនឱ្យដំឡើង។"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់កម្មវិធីមិនត្រូវគ្នាជាមួយកញ្ចប់ដែលមានស្រាប់។"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"អ្នកប្រើប្រាស់នេះមិនអាចដំឡើងកម្មវិធីមិនស្គាល់បានទេ"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"មិនអនុញ្ញាតឱ្យអ្នកប្រើប្រាស់នេះដំឡើងកម្មវិធីទេ"</string>
<string name="ok" msgid="7871959885003339302">"យល់ព្រម"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"គ្រប់គ្រងកម្មវិធី"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"អស់ទំហំផ្ទុក"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"មិនអាចដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> បានទេ។ សូមបង្កើនទំហំផ្ទុកទំនេរមួយចំនួន រួចព្យាយាមម្ដងទៀត។"</string>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index fe8144e..43aaab1 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ನೀವು ಈ ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ನೀವು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ಆ್ಯಪ್ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿಲ್ಲ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವ ಪ್ಯಾಕೇಜ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ಪ್ಯಾಕೇಜ್ನಂತೆ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿರುವ ಆ್ಯಪ್ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ಈ ಬಳಕೆದಾರರು ಅಪರಿಚಿತ ಆ್ಯಪ್ಗಳನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ಆ್ಯಪ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಈ ಬಳಕೆದಾರರನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
<string name="ok" msgid="7871959885003339302">"ಸರಿ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ಆ್ಯಪ್ ನಿರ್ವಹಿಸಿ"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ಸಂಗ್ರಹಣೆ ಖಾಲಿ ಇಲ್ಲ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಕೊಂಚ ಸ್ಥಳವನ್ನು ಖಾಲಿ ಮಾಡಿ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index 4bfa3cc..9da1182 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"앱이 설치되었습니다."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"이 앱을 설치하시겠습니까?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"이 앱을 업데이트하시겠습니까?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"앱이 설치되지 않았습니다."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"패키지 설치가 차단되었습니다."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"이 사용자는 알 수 없는 앱을 설치할 수 없습니다."</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"이 사용자는 앱을 설치할 권한이 없습니다."</string>
<string name="ok" msgid="7871959885003339302">"확인"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"앱 관리"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"여유 공간이 없음"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다. 여유 공간을 늘린 후에 다시 시도하세요."</string>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 5888b7b..00a32f4 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Колдонмо орнотулду."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Бул колдонмону орнотоюн деп жатасызбы?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Бул колдонмону жаңыртайын деп жатасызбы?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Колдонмо орнотулган жок."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Топтомду орнотууга болбойт."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Бул колдонуучу белгисиз колдонмолорду орното албайт"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Бул колдонуучу колдонмолорду орното албайт"</string>
<string name="ok" msgid="7871959885003339302">"ЖАРАЙТ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Колд. башкаруу"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Бош орун жок"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес. Орун бошотуп, кайталап орнотуп көрүңүз."</string>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index f9866b0..3cce796 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ຕິດຕັ້ງແອັບແລ້ວ."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບນີ້ບໍ່?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ທ່ານຕ້ອງການອັບເດດແອັບນີ້ບໍ່?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເທື່ອ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ແພັກເກດຖືກບລັອກບໍ່ໃຫ້ໄດ້ຮັບການຕິດຕັ້ງ."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແພັກເກດຂັດແຍ່ງກັບແພັກເກດທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ຜູ້ໃຊ້ນີ້ບໍ່ສາມາດຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກໄດ້"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ຜູ້ໃຊ້ນີ້ບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບໄດ້"</string>
<string name="ok" msgid="7871959885003339302">"ຕົກລົງ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ຈັດການແອັບ"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ພື້ນທີ່ຫວ່າງບໍ່ພຽງພໍ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໄດ້. ກະລຸນາລຶບຂໍ້ມູນທີ່ບໍ່ຈຳເປັນອອກເພື່ອໃຫ້ມີບ່ອນຈັດເກັບຂໍ້ມູນຫວ່າງເພີ່ມຂຶ້ນ ແລ້ວລອງໃໝ່ອີກຄັ້ງ."</string>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 9bf018b..a7ec560e 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -26,6 +26,7 @@
<string name="install_done" msgid="5987363587661783896">"Programa įdiegta."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ar norite įdiegti šią programą?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ar norite atnaujinti šią programą?"</string>
+ <string name="install_confirm_question_update_owner_reminder" msgid="3750986542284587290">"Atnaujinti šią programą iš <xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>?\n\nŠi programa įprastai gauna naujinius iš <xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>. Atnaujinę iš kito šaltinio, būsimus naujinius galite gauti iš bet kurio šaltinio telefone. Gali būti pakeistos programos funkcijos."</string>
<string name="install_failed" msgid="5777824004474125469">"Programa neįdiegta."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketas užblokuotas ir negali būti įdiegtas."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
@@ -41,6 +42,7 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Šis naudotojas negali diegti nežinomų programų"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Šiam naudotojui neleidžiama diegti programų"</string>
<string name="ok" msgid="7871959885003339302">"Gerai"</string>
+ <string name="update_anyway" msgid="8792432341346261969">"Vis tiek atnaujinti"</string>
<string name="manage_applications" msgid="5400164782453975580">"Tvark. progr."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nėra vietos"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nepavyko įdiegti programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“. Atlaisvinkite vietos ir bandykite dar kartą."</string>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index 823858c..55a9f3c 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Lietotne ir instalēta."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vai vēlaties instalēt šo lietotni?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vai vēlaties atjaunināt šo lietotni?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Lietotne nav instalēta."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakotnes instalēšana tika bloķēta."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Lietotne netika instalēta, jo pastāv pakotnes konflikts ar esošu pakotni."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Šis lietotājs nevar instalēt nezināmas lietotnes"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Šim lietotājam nav atļauts instalēt lietotnes"</string>
<string name="ok" msgid="7871959885003339302">"Labi"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Pārv. lietotnes"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nav brīvas vietas"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt. Atbrīvojiet vietu un mēģiniet vēlreiz."</string>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index 529ea3e..4024d8a 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Апликацијата е инсталирана."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Дали сакате да ја инсталирате апликацијава?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Дали сакате да ја ажурирате апликацијава?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Апликацијата не е инсталирана."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирањето на пакетот е блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Апликација што не е инсталирана како пакет е во конфликт со постоечки пакет."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Корисников не може да инсталира непознати апликации"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"На корисников не му е дозволено да инсталира апликации"</string>
<string name="ok" msgid="7871959885003339302">"Во ред"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Управување со апликациите"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема простор"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> не може да се инсталира. Ослободете простор и обидете се повторно."</string>
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
index 43cac7a..42790b2 100644
--- a/packages/PackageInstaller/res/values-ml/strings.xml
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തു."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ഈ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യണോ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ഈ ആപ്പ് അപ്ഡേറ്റ് ചെയ്യണോ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തിട്ടില്ല."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"പാക്കേജ് ഇൻസ്റ്റാൾ ചെയ്യുന്നത് ബ്ലോക്ക് ചെയ്തു."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"പാക്കേജിന് നിലവിലുള്ള പാക്കേജുമായി പൊരുത്തക്കേടുള്ളതിനാൽ, ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ഈ ഉപയോക്താവിന്, അജ്ഞാത ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാനാവില്ല"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാൻ ഈ ഉപയോക്താവിന് അനുവാദമില്ല"</string>
<string name="ok" msgid="7871959885003339302">"ശരി"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ആപ്പുകൾ മാനേജ് ചെയ്യുക"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ഇടമില്ല"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാൾ ചെയ്യാനായില്ല. കുറച്ച് ഇടമുണ്ടാക്കി, വീണ്ടും ശ്രമിക്കുക."</string>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index 0243931..01e7aec 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Аппыг суулгасан."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Та энэ аппыг суулгахыг хүсэж байна уу?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Та энэ аппыг шинэчлэхийг хүсэж байна уу?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Аппыг суулгаагүй."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Багц суулгахыг блоклосон байна."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Багц одоо байгаа багцтай тохирохгүй байгаа тул аппыг суулгаж чадсангүй."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Энэ хэрэглэгч тодорхойгүй апп суулгах боломжгүй"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Энэ хэрэглэгч нь апп суулгах зөвшөөрөлгүй байна"</string>
<string name="ok" msgid="7871959885003339302">"ОК"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Аппуудыг удирдах"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Орон зай дутагдаж байна"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г суулгаж чадсангүй. Хэсэг зай чөлөөлөөд дахин оролдоно уу."</string>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index 8a4ff44..5ae257a 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"अॅप इंस्टॉल झाले."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"तुम्हाला हे ॲप इंस्टॉल करायचे आहे का?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"तुम्हाला हे ॲप अपडेट करायचे आहे का?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"अॅप इंस्टॉल झाले नाही."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"पॅकेज इंस्टॉल होण्यापासून ब्लॉक केले होते."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल झाले नाही."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"या वापरकर्त्याद्वारे अज्ञात अॅप्स इंस्टॉल केली जाऊ शकत नाहीत"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"या वापरकर्त्याला अॅप्स इंस्टॉल करण्याची अनुमती नाही"</string>
<string name="ok" msgid="7871959885003339302">"ओके"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"अॅप्स व्यवस्थापन"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"जागा संपली"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> इंस्टॉल केले जाऊ शकत नाही. काही जागा मोकळी करा आणि पुन्हा प्रयत्न करा."</string>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
index 13531bd..a26d274 100644
--- a/packages/PackageInstaller/res/values-ms/strings.xml
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikasi dipasang."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Adakah anda ingin memasang aplikasi ini?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Adakah anda mahu mengemas kini apl ini?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak dipasang."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakej ini telah disekat daripada dipasang."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Apl tidak dipasang kerana pakej bercanggah dengan pakej yang sedia ada."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apl yang tidak diketahui tidak boleh dipasang oleh pengguna ini"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Pengguna ini tidak dibenarkan memasang apl"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Urus apl"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kehabisan ruang"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebahagian ruang dan cuba lagi."</string>
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
index 4dbf3fc..db21cf7 100644
--- a/packages/PackageInstaller/res/values-my/strings.xml
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"အက်ပ်ထည့်သွင်းပြီးပါပြီ။"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ဤအက်ပ်ကို ထည့်သွင်းလိုသလား။"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ဤအက်ပ်ကို အပ်ဒိတ်လုပ်လိုသလား။"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"အက်ပ်မထည့်သွင်းရသေးပါ"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ပက်ကေ့ဂျ်ထည့်သွင်းခြင်းကို ပိတ်ထားသည်။"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် လက်ရှိပက်ကေ့ဂျ်နှင့် တိုက်နေသည်။"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"အရင်းအမြစ်မသိသော အက်ပ်များကို ဤအသုံးပြုသူက ထည့်သွင်းခွင့်မရှိပါ"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ဤအသုံးပြုသူသည် အက်ပ်များကို ထည့်သွင်းခွင့်မရှိပါ"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"အက်ပ်စီမံခြင်း"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"နေရာလွတ်မရှိပါ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ထည့်သွင်း၍ မရနိုင်ပါ။ နေရာလွတ်ပြုလုပ်ပြီး ထပ်စမ်းကြည့်ပါ။"</string>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index 8ec94e0..94b7f50 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Appen er installert."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne appen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du oppdatere denne appen?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Appen ble ikke installert."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakken er blokkert fra å bli installert."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ukjente apper kan ikke installeres av denne brukeren"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Brukeren har ikke tillatelse til å installere apper"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Administrer apper"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Tom for plass"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigjør plass og prøv på nytt."</string>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index d6451eb..d531d5c 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"एप इन्स्टल गरियो।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"तपाईं यो एप इन्स्टल गर्न चाहनुहुन्छ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"तपाईं यो एप अपडेट गर्न चाहनुहुन्छ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"एप स्थापना गरिएन।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको एप विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"यी प्रयोगकर्ता अज्ञात एपहरू इन्स्टल गर्न सक्नुहुन्न"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"यो प्रयोगकर्तालाई एपहरू इन्स्टल गर्ने अनुमति छैन"</string>
<string name="ok" msgid="7871959885003339302">"ठिक छ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"एपको प्रबन्ध गर्नु…"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"खाली ठाउँ छैन"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन। केही ठाउँ खाली गरेर फेरि प्रयास गर्नुहोस्।"</string>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index c0a3c8e..ad4df64 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App geïnstalleerd."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Wil je deze app installeren?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Wil je deze app updaten?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"App niet geïnstalleerd."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"De installatie van het pakket is geblokkeerd."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Onbekende apps kunnen niet worden geïnstalleerd door deze gebruiker"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Deze gebruiker mag geen apps installeren"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Apps beheren"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Geen ruimte beschikbaar"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd. Maak ruimte vrij en probeer het opnieuw."</string>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 965c7d8a..db908fd 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ଆପଣ ଏହି ଆପକୁ ଇନଷ୍ଟଲ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ଆପଣ ଏହି ଆପକୁ ଅପଡେଟ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ଏହି ପ୍ୟାକେଜ୍କୁ ଇନଷ୍ଟଲ୍ କରାଯିବାରୁ ଅବରୋଧ କରାଯାଇଥିଲା।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ପୂର୍ବରୁ ଥିବା ପ୍ୟାକେଜ୍ ସହ ଏହି ପ୍ୟାକେଜ୍ର ସମସ୍ୟା ଉପୁଯିବାରୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ଏହି ୟୁଜରଙ୍କ ଦ୍ୱାରା ଅଜଣା ଆପ୍ ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ଏହି ୟୁଜର୍ ଆପ୍ ଇନଷ୍ଟଲ୍ କରିପାରିବେ ନାହିଁ"</string>
<string name="ok" msgid="7871959885003339302">"ଠିକ୍ ଅଛି"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ଆପ୍ଗୁଡ଼ିକର ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ଆଉ ସ୍ଥାନ ନାହିଁ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ। କିଛି ସ୍ଥାନ ଖାଲିକରି ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index 2a3068c..64dd9c7 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ਐਪ ਸਥਾਪਤ ਕੀਤੀ ਗਈ।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਤ ਹੋਣ ਤੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ਇਹ ਵਰਤੋਂਕਾਰ ਅਗਿਆਤ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕਰ ਸਕਦਾ"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
<string name="ok" msgid="7871959885003339302">"ਠੀਕ ਹੈ"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ਐਪਾਂ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ਜਗ੍ਹਾ ਖਾਲੀ ਨਹੀਂ"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕੁਝ ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index dc4e0c9..c05c81a 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacja została zainstalowana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Zainstalować tę aplikację?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Zaktualizować tę aplikację?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacja nie została zainstalowana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalacja pakietu została zablokowana."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ten użytkownik nie może instalować nieznanych aplikacji"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ten użytkownik nie może instalować aplikacji"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Zarządzaj aplikacjami"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Brak miejsca"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>. Zwolnij trochę miejsca i spróbuj ponownie."</string>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index a5ee82b..f2eab25 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App instalado."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apps desconhecidos não podem ser instalados por este usuário"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuário não tem permissão para instalar apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gerenciar apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index 9e80a97..c440880 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App instalada."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Instalar esta app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Pretende atualizar esta app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplicação não instalada."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Foi bloqueada a instalação do pacote."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"A app não foi instalada porque o pacote entra em conflito com um pacote existente."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este utilizador não pode instalar aplicações desconhecidas."</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este utilizador não tem autorização para instalar aplicações."</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gerir app"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar a app <xliff:g id="APP_NAME">%1$s</xliff:g>. Liberte algum espaço e tente novamente."</string>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index a5ee82b..f2eab25 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"App instalado."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apps desconhecidos não podem ser instalados por este usuário"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuário não tem permissão para instalar apps"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gerenciar apps"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index 09693bf..f12e364 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplicație instalată."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vrei să instalezi această aplicație?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vrei să actualizezi această aplicație?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplicația nu a fost instalată."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalarea pachetului a fost blocată."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplicația nu a fost instalată deoarece pachetul intră în conflict cu un pachet existent."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplicațiile necunoscute nu pot fi instalate de acest utilizator"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Acest utilizator nu are permisiunea să instaleze aplicații"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Gestionează"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Spațiu de stocare insuficient"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată. Eliberează spațiu și încearcă din nou."</string>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index f70c4bc..e7e9e33 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Приложение установлено."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Установить приложение?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Обновить приложение?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Приложение не установлено."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Установка пакета заблокирована."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Этот пользователь не может устанавливать неизвестные приложения."</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Этому пользователю не разрешено устанавливать приложения."</string>
<string name="ok" msgid="7871959885003339302">"ОК"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Управление приложениями"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Недостаточно места"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Освободите место на устройстве и повторите попытку."</string>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index cfe29cb..0f5dbb6 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"යෙදුම ස්ථාපනය කර ඇත."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්යද?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ඔබට මෙම යෙදුම යාවත්කාලීන කිරීමට අවශ්යද?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"යෙදුම ස්ථාපනය කර නැත."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"මෙම පරිශීලකයා මඟින් නොදන්නා යෙදුම් ස්ථාපනය කළ නොහැක"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"මෙම පරිශීලකයාට යෙදුම් ස්ථාපනය කිරීමට අවසර නැත"</string>
<string name="ok" msgid="7871959885003339302">"හරි"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"යෙදුම් කළමනාකරණය කරන්න"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ඉඩ නොමැත"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපිත කිරීමට නොහැකි විය. ඉඩ පොඩ්ඩක් නිදහස් කොට නැවත උත්සාහ කරන්න."</string>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index 181ff9c..8363fb6 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikácia bola nainštalovaná."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Chcete túto aplikáciu nainštalovať?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete túto aplikáciu aktualizovať?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikácia nebola nainštalovaná."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Inštalácia balíka bola zablokovaná."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikácia sa nenainštalovala, pretože balík je v konflikte s existujúcim balíkom."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tento používateľ nemôže inštalovať neznáme aplikácie"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tento používateľ nemá povolené inštalovať aplikácie"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Spravovať aplikácie"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatok miesta"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať. Uvoľnite miesto v pamäti a skúste to znova."</string>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index 35b3fda..5c28979 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je nameščena."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ali želite namestiti to aplikacijo?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ali želite posodobiti to aplikacijo?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacija ni nameščena."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Namestitev paketa je bila blokirana."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija ni bila nameščena, ker je paket v navzkrižju z obstoječim paketom."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ta uporabnik nima dovoljenja za nameščanje neznanih aplikacij"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ta uporabnik nima dovoljenja za nameščanje aplikacij"</string>
<string name="ok" msgid="7871959885003339302">"V redu"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Upravlj. aplik."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Zmanjkalo je prostora"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti. Sprostite prostor in poskusite znova."</string>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index f58efea..709b7fd 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacioni u instalua."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Dëshiron ta instalosh këtë aplikacion?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Dëshiron ta përditësosh këtë aplikacion?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Aplikacioni nuk u instalua."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalimi paketës u bllokua."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplikacionet e panjohura nuk mund të instalohen nga ky përdorues"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ky përdorues nuk lejohet të instalojë aplikacione"</string>
<string name="ok" msgid="7871959885003339302">"Në rregull"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Menaxho aplikacionet"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nuk ka hapësirë"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej. Liro pak hapësirë dhe provo përsëri."</string>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 2e448ad..3a62db3 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Апликација је инсталирана."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Желите да инсталирате ову апликацију?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Желите да ажурирате ову апликацију?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Апликација није инсталирана."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирање пакета је блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Овај корисник не може да инсталира непознате апликације"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Овом кориснику није дозвољено да инсталира апликације"</string>
<string name="ok" msgid="7871959885003339302">"Потврди"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Управљајте апл."</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема више простора"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите простор и пробајте поново."</string>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index cb12c91..d8ed4b1 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Appen har installerats."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vill du installera den här appen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vill du uppdatera den här appen?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Appen har inte installerats."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketet har blockerats för installation."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Denna användare får inte installera okända appar"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Användaren har inte behörighet att installera appar"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Hantera appar"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Slut på utrymme"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Det gick inte att avinstallera <xliff:g id="APP_NAME">%1$s</xliff:g>. Frigör minne och försök igen."</string>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index 64e24f9..4919cb55 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Imesakinisha programu."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ungependa kusakinisha programu hii?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ungependa kusasisha programu hii?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Imeshindwa kusakinisha programu."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Kifurushi kimezuiwa kisisakinishwe."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Programu haikusakinishwa kwa sababu kifurushi kinakinzana na kifurushi kingine kilichopo."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Mtumiaji huyu hana idhini ya kusakinisha programu ambazo hazijulikani"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Mtumiaji huyu haruhusiwi kusakinisha programu"</string>
<string name="ok" msgid="7871959885003339302">"Sawa"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Dhibiti programu"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nafasi imejaa"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Imeshindwa kusakinisha <xliff:g id="APP_NAME">%1$s</xliff:g>. Futa baadhi ya maudhui ili upate nafasi kisha ujaribu tena."</string>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index 71970c4..d867ee8 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ஆப்ஸ் நிறுவப்பட்டது."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"இந்த ஆப்ஸை நிறுவ வேண்டுமா?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ஆப்ஸ் நிறுவப்படவில்லை."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"இந்தத் தொகுப்பு நிறுவப்படுவதிலிருந்து தடுக்கப்பட்டது."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"இந்தத் தொகுப்பு ஏற்கனவே உள்ள தொகுப்புடன் முரண்படுவதால் ஆப்ஸ் நிறுவப்படவில்லை."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"அறியப்படாத ஆப்ஸை இந்தப் பயனரால் நிறுவ இயலாது"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ஆப்ஸை நிறுவ இந்தப் பயனருக்கு அனுமதியில்லை"</string>
<string name="ok" msgid="7871959885003339302">"சரி"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ஆப்ஸை நிர்வகி"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"போதுமான சேமிப்பிடம் இல்லை"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை நிறுவ இயலவில்லை. சிறிது சேமிப்பிடத்தைக் காலிசெய்து மீண்டும் முயலவும்."</string>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index 67a15fb..7e1c9da 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"యాప్ ఇన్స్టాల్ చేయబడింది."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"మీరు ఈ యాప్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"మీరు ఈ యాప్ను అప్డేట్ చేయాలనుకుంటున్నారా?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ప్యాకేజీ ఇన్స్టాల్ కాకుండా బ్లాక్ చేయబడింది."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ప్యాకేజీ, అలాగే ఇప్పటికే ఉన్న ప్యాకేజీ మధ్య వైరుధ్యం ఉన్నందున యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ఈ వినియోగదారు తెలియని యాప్లను ఇన్స్టాల్ చేయలేరు"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"యాప్లను ఇన్స్టాల్ చేయడానికి ఈ వినియోగదారుకు అనుమతి లేదు"</string>
<string name="ok" msgid="7871959885003339302">"సరే"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"యాప్లను నిర్వహించండి"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ఖాళీ లేదు"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని ఇన్స్టాల్ చేయడం సాధ్యపడలేదు. కొంత స్థలాన్ని ఖాళీ చేసి మళ్లీ ప్రయత్నించండి."</string>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index de8f727..37caaa7 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ติดตั้งแอปแล้ว"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"คุณต้องการติดตั้งแอปนี้ไหม"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"คุณต้องการอัปเดตแอปนี้ไหม"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ไม่ได้ติดตั้งแอป"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"ผู้ใช้รายนี้ไม่สามารถติดตั้งแอปที่ไม่รู้จัก"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ผู้ใช้รายนี้ไม่ได้รับอนุญาตให้ติดตั้งแอป"</string>
<string name="ok" msgid="7871959885003339302">"ตกลง"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"จัดการแอป"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"ไม่มีพื้นที่"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"ติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้ เพิ่มพื้นที่ว่างแล้วลองอีกครั้ง"</string>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index add4258..87c408a 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Na-install na ang app."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Gusto mo bang i-install ang app na ito?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Gusto mo bang i-update ang app na ito?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Hindi na-install ang app."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Na-block ang pag-install sa package."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Hindi maaaring mag-install ang user na ito ng mga hindi kilalang app"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Hindi pinapayagan ang user na ito na mag-install ng mga app"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Pamahalaan ang app"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Wala nang espasyo"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukan ulit."</string>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index a006c06..a775b4c 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Uygulama yüklendi."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bu uygulamayı yüklemek istiyor musunuz?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bu uygulamayı güncellemek istiyor musunuz?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Uygulama yüklenmedi."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin yüklemesi engellendi."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Bilinmeyen uygulamalar bu kullanıcı tarafından yüklenemez"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu kullanıcının uygulama yüklemesine izin verilmiyor"</string>
<string name="ok" msgid="7871959885003339302">"Tamam"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Uygulamaları yönet"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Yer kalmadı"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> yüklenemedi. Boş alan açın ve yeniden deneyin."</string>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index d8928e5..ab07754 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Програму встановлено."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Установити цей додаток?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Оновити цей додаток?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Програму не встановлено."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Встановлення пакета заблоковано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Цей користувач не може встановлювати невідомі додатки"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Цей користувач не може встановлювати додатки"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Керувати додатками"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Недостат. місця"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити. Звільніть місце та повторіть спробу."</string>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index 21f6cdf..4f23cd2 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"ایپ انسٹال ہو گئی۔"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"کیا آپ یہ ایپ انسٹال کرنا چاہتے ہیں؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"کیا آپ یہ ایپ اپ ڈیٹ کرنا چاہتے ہیں؟"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"ایپ انسٹال نہیں ہوئی۔"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"پیکج کو انسٹال ہونے سے مسدود کر دیا گیا تھا۔"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ایپ انسٹال نہیں ہوئی کیونکہ پیکج ایک موجودہ پیکیج سے متصادم ہے۔"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"یہ صارف نامعلوم ایپس کو انسٹال نہیں کر سکتا"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"اس صارف کو ایپس انسٹال کرنے کی اجازت نہیں ہے"</string>
<string name="ok" msgid="7871959885003339302">"ٹھیک ہے"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"ایپس منظم کریں"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"جگہ نہیں ہے"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو انسٹال نہیں کیا جا سکا۔ کچھ جگہ خالی کریں اور دوبارہ کوشش کریں۔"</string>
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
index bb225bc..48d8681 100644
--- a/packages/PackageInstaller/res/values-uz/strings.xml
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Ilova o‘rnatildi."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bu ilovani oʻrnatmoqchimisiz?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bu ilova yangilansinmi?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Ilova o‘rnatilmadi."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paket o‘rnatilishga qarshi bloklangan."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Paket mavjud paket bilan zid kelganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Notanish ilovalarni bu foydalanuvchi tomonidan o‘rnatib bo‘lmaydi"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu foydalanuvchiga ilovalarni o‘rnatish uchun ruxsat berilmagan"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Ilovalarni boshqarish"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Joy qolmadi"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘rnatilmadi. Xotiradan biroz joy bo‘shating va qaytadan urining."</string>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 1e0df14..4cc563d 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Ứng dụng đã được cài đặt."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bạn có muốn cài đặt ứng dụng này không?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bạn có muốn cập nhật ứng dụng này không?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Ứng dụng chưa được cài đặt."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Đã chặn cài đặt gói."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Chưa cài đặt được ứng dụng do gói xung đột với một gói hiện có."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Người dùng này không thể cài đặt ứng dụng không xác định"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Người dùng này không được phép cài đặt ứng dụng"</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Quản lý ứng dụng"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Hết dung lượng"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>. Hãy giải phóng dung lượng và thử lại."</string>
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
index f25da81..b4bf413 100644
--- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"已安装应用。"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"要安装此应用吗?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"要更新此应用吗?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"未安装应用。"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"系统已禁止安装该软件包。"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"应用未安装:软件包与现有软件包存在冲突。"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"该用户无法安装未知应用"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"此用户无权安装应用"</string>
<string name="ok" msgid="7871959885003339302">"确定"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"管理应用"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"空间不足"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"无法安装<xliff:g id="APP_NAME">%1$s</xliff:g>。请释放一些存储空间并重试。"</string>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 46f3b9f..0c4ed6c 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"要安裝此應用程式嗎?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"要更新此應用程式嗎?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"套件已遭封鎖,無法安裝。"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"此使用者無法安裝來源不明的應用程式"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"此使用者無法安裝應用程式"</string>
<string name="ok" msgid="7871959885003339302">"確定"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"管理應用程式"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"儲存空間不足"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先騰出一些儲存空間,然後再試一次。"</string>
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
index cf8cd59..9b7bda6 100644
--- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"要安裝這個應用程式嗎?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"要更新這個應用程式嗎?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"系統已封鎖這個套件,因此無法安裝。"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"應用程式套件與現有套件衝突,因此未能完成安裝。"</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"這位使用者無法安裝不明的應用程式"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"這位使用者無法安裝應用程式"</string>
<string name="ok" msgid="7871959885003339302">"確定"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"管理應用程式"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"空間不足"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先釋出部分空間,然後再試一次。"</string>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index afdfd82..7317abc 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -26,6 +26,8 @@
<string name="install_done" msgid="5987363587661783896">"Uhlelo lokusebenza olufakiwe."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ingabe ufuna ukufaka le app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ingabe ufuna ukubuyekeza le app?"</string>
+ <!-- no translation found for install_confirm_question_update_owner_reminder (3750986542284587290) -->
+ <skip />
<string name="install_failed" msgid="5777824004474125469">"Uhlelo lokusebenza alufakiwe."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Iphakheji livinjiwe kusukela ekufakweni."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
@@ -41,6 +43,8 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Izinhlelo zokusebenza ezingaziwa azikwazi ukufakwa ilo msebenzisi"</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Lo msebenzisi akavunyelwe ukufaka izinhlelo zokusebenza"</string>
<string name="ok" msgid="7871959885003339302">"KULUNGILE"</string>
+ <!-- no translation found for update_anyway (8792432341346261969) -->
+ <skip />
<string name="manage_applications" msgid="5400164782453975580">"Phatha izinhlelo zokusebenza"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Iphelelwe yisikhala"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa. Khulula isikhala bese uzama futhi."</string>
diff --git a/packages/SettingsLib/Spa/build.gradle b/packages/SettingsLib/Spa/build.gradle
index 2071489..4fd2b5d 100644
--- a/packages/SettingsLib/Spa/build.gradle
+++ b/packages/SettingsLib/Spa/build.gradle
@@ -24,7 +24,7 @@
}
}
plugins {
- id 'com.android.application' version '8.0.0-beta03' apply false
- id 'com.android.library' version '8.0.0-beta03' apply false
+ id 'com.android.application' version '8.0.0-beta05' apply false
+ id 'com.android.library' version '8.0.0-beta05' apply false
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}
diff --git a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
index c3d5431..ed85e33 100644
--- a/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
@@ -16,7 +16,7 @@
#Thu Jul 14 10:36:06 CST 2022
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-rc-2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle
index 4563b7d..9962c93 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -79,7 +79,7 @@
api "androidx.compose.ui:ui-tooling-preview:$jetpack_compose_version"
api "androidx.lifecycle:lifecycle-livedata-ktx"
api "androidx.lifecycle:lifecycle-runtime-compose"
- api "androidx.navigation:navigation-compose:2.6.0-alpha04"
+ api "androidx.navigation:navigation-compose:2.6.0-alpha07"
api "com.github.PhilJay:MPAndroidChart:v3.1.0-alpha"
api "com.google.android.material:material:1.7.0-alpha03"
debugApi "androidx.compose.ui:ui-tooling:$jetpack_compose_version"
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index f741f65..7b4c862 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -51,7 +51,8 @@
public CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
mContext = context;
mBtManager = localBtManager;
- mHearingAidDeviceManager = new HearingAidDeviceManager(localBtManager, mCachedDevices);
+ mHearingAidDeviceManager = new HearingAidDeviceManager(context, localBtManager,
+ mCachedDevices);
mCsipDeviceManager = new CsipDeviceManager(localBtManager, mCachedDevices);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java
new file mode 100644
index 0000000..d8475b3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Constant values used to configure hearing aid audio routing.
+ *
+ * {@link HearingAidAudioRoutingHelper}
+ */
+public final class HearingAidAudioRoutingConstants {
+ public static final int[] CALL_ROUTING_ATTRIBUTES = new int[] {
+ // Stands for STRATEGY_PHONE
+ AudioAttributes.USAGE_VOICE_COMMUNICATION,
+ };
+
+ public static final int[] MEDIA_ROUTING_ATTRIBUTES = new int[] {
+ // Stands for STRATEGY_MEDIA, including USAGE_GAME, USAGE_ASSISTANT,
+ // USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, USAGE_ASSISTANCE_SONIFICATION
+ AudioAttributes.USAGE_MEDIA
+ };
+
+ public static final int[] RINGTONE_ROUTING_ATTRIBUTE = new int[] {
+ // Stands for STRATEGY_SONIFICATION, including USAGE_ALARM
+ AudioAttributes.USAGE_NOTIFICATION_RINGTONE
+ };
+
+ public static final int[] SYSTEM_SOUNDS_ROUTING_ATTRIBUTES = new int[] {
+ // Stands for STRATEGY_SONIFICATION_RESPECTFUL, including USAGE_NOTIFICATION_EVENT
+ AudioAttributes.USAGE_NOTIFICATION,
+ // Stands for STRATEGY_ACCESSIBILITY
+ AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY,
+ // Stands for STRATEGY_DTMF
+ AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING,
+ };
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ RoutingValue.AUTO,
+ RoutingValue.HEARING_DEVICE,
+ RoutingValue.DEVICE_SPEAKER,
+ })
+
+ public @interface RoutingValue {
+ int AUTO = 0;
+ int HEARING_DEVICE = 1;
+ int DEVICE_SPEAKER = 2;
+ }
+
+ public static final AudioDeviceAttributes DEVICE_SPEAKER_OUT = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java
new file mode 100644
index 0000000..c9512cd
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.audiopolicy.AudioProductStrategy;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * A helper class to configure the routing strategy for hearing aids.
+ */
+public class HearingAidAudioRoutingHelper {
+
+ private final AudioManager mAudioManager;
+
+ public HearingAidAudioRoutingHelper(Context context) {
+ mAudioManager = context.getSystemService(AudioManager.class);
+ }
+
+ /**
+ * Gets the list of {@link AudioProductStrategy} referred by the given list of usage values
+ * defined in {@link AudioAttributes}
+ */
+ public List<AudioProductStrategy> getSupportedStrategies(int[] attributeSdkUsageList) {
+ final List<AudioAttributes> audioAttrList = new ArrayList<>(attributeSdkUsageList.length);
+ for (int attributeSdkUsage : attributeSdkUsageList) {
+ audioAttrList.add(new AudioAttributes.Builder().setUsage(attributeSdkUsage).build());
+ }
+
+ final List<AudioProductStrategy> allStrategies = getAudioProductStrategies();
+ final List<AudioProductStrategy> supportedStrategies = new ArrayList<>();
+ for (AudioProductStrategy strategy : allStrategies) {
+ for (AudioAttributes audioAttr : audioAttrList) {
+ if (strategy.supportsAudioAttributes(audioAttr)) {
+ supportedStrategies.add(strategy);
+ }
+ }
+ }
+
+ return supportedStrategies.stream().distinct().collect(Collectors.toList());
+ }
+
+ /**
+ * Sets the preferred device for the given strategies.
+ *
+ * @param supportedStrategies A list of {@link AudioProductStrategy} used to configure audio
+ * routing
+ * @param hearingDevice {@link AudioDeviceAttributes} of the device to be changed in audio
+ * routing
+ * @param routingValue one of value defined in
+ * {@link HearingAidAudioRoutingConstants.RoutingValue}, denotes routing
+ * destination.
+ * @return {code true} if the routing value successfully configure
+ */
+ public boolean setPreferredDeviceRoutingStrategies(
+ List<AudioProductStrategy> supportedStrategies, AudioDeviceAttributes hearingDevice,
+ @HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
+ boolean status;
+ switch (routingValue) {
+ case HearingAidAudioRoutingConstants.RoutingValue.AUTO:
+ status = removePreferredDeviceForStrategies(supportedStrategies);
+ return status;
+ case HearingAidAudioRoutingConstants.RoutingValue.HEARING_DEVICE:
+ status = removePreferredDeviceForStrategies(supportedStrategies);
+ status &= setPreferredDeviceForStrategies(supportedStrategies, hearingDevice);
+ return status;
+ case HearingAidAudioRoutingConstants.RoutingValue.DEVICE_SPEAKER:
+ status = removePreferredDeviceForStrategies(supportedStrategies);
+ status &= setPreferredDeviceForStrategies(supportedStrategies,
+ HearingAidAudioRoutingConstants.DEVICE_SPEAKER_OUT);
+ return status;
+ default:
+ throw new IllegalArgumentException("Unexpected routingValue: " + routingValue);
+ }
+ }
+
+ /**
+ * Gets the matched hearing device {@link AudioDeviceAttributes} for {@code device}.
+ *
+ * <p>Will also try to match the {@link CachedBluetoothDevice#getSubDevice()} of {@code device}
+ *
+ * @param device the {@link CachedBluetoothDevice} need to be hearing aid device
+ * @return the requested AudioDeviceAttributes or {@code null} if not match
+ */
+ @Nullable
+ public AudioDeviceAttributes getMatchedHearingDeviceAttributes(CachedBluetoothDevice device) {
+ if (device == null || !device.isHearingAidDevice()) {
+ return null;
+ }
+
+ AudioDeviceInfo[] audioDevices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+ for (AudioDeviceInfo audioDevice : audioDevices) {
+ // ASHA for TYPE_HEARING_AID, HAP for TYPE_BLE_HEADSET
+ if (audioDevice.getType() == AudioDeviceInfo.TYPE_HEARING_AID
+ || audioDevice.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) {
+ if (matchAddress(device, audioDevice)) {
+ return new AudioDeviceAttributes(audioDevice);
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean matchAddress(CachedBluetoothDevice device, AudioDeviceInfo audioDevice) {
+ final String audioDeviceAddress = audioDevice.getAddress();
+ final CachedBluetoothDevice subDevice = device.getSubDevice();
+ final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
+
+ return device.getAddress().equals(audioDeviceAddress)
+ || (subDevice != null && subDevice.getAddress().equals(audioDeviceAddress))
+ || (!memberDevices.isEmpty() && memberDevices.stream().anyMatch(
+ m -> m.getAddress().equals(audioDeviceAddress)));
+ }
+
+ private boolean setPreferredDeviceForStrategies(List<AudioProductStrategy> strategies,
+ AudioDeviceAttributes audioDevice) {
+ boolean status = true;
+ for (AudioProductStrategy strategy : strategies) {
+ status &= mAudioManager.setPreferredDeviceForStrategy(strategy, audioDevice);
+
+ }
+
+ return status;
+ }
+
+ private boolean removePreferredDeviceForStrategies(List<AudioProductStrategy> strategies) {
+ boolean status = true;
+ for (AudioProductStrategy strategy : strategies) {
+ status &= mAudioManager.removePreferredDeviceForStrategy(strategy);
+ }
+
+ return status;
+ }
+
+ @VisibleForTesting
+ public List<AudioProductStrategy> getAudioProductStrategies() {
+ return AudioManager.getAudioProductStrategies();
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index ebfec0a..4354e0c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -18,6 +18,11 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.media.AudioDeviceAttributes;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.provider.Settings;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -33,12 +38,25 @@
private static final String TAG = "HearingAidDeviceManager";
private static final boolean DEBUG = BluetoothUtils.D;
+ private final ContentResolver mContentResolver;
private final LocalBluetoothManager mBtManager;
private final List<CachedBluetoothDevice> mCachedDevices;
- HearingAidDeviceManager(LocalBluetoothManager localBtManager,
+ private final HearingAidAudioRoutingHelper mRoutingHelper;
+ HearingAidDeviceManager(Context context, LocalBluetoothManager localBtManager,
List<CachedBluetoothDevice> CachedDevices) {
+ mContentResolver = context.getContentResolver();
mBtManager = localBtManager;
mCachedDevices = CachedDevices;
+ mRoutingHelper = new HearingAidAudioRoutingHelper(context);
+ }
+
+ @VisibleForTesting
+ HearingAidDeviceManager(Context context, LocalBluetoothManager localBtManager,
+ List<CachedBluetoothDevice> cachedDevices, HearingAidAudioRoutingHelper routingHelper) {
+ mContentResolver = context.getContentResolver();
+ mBtManager = localBtManager;
+ mCachedDevices = cachedDevices;
+ mRoutingHelper = routingHelper;
}
void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice) {
@@ -192,12 +210,11 @@
case BluetoothProfile.STATE_CONNECTED:
onHiSyncIdChanged(cachedDevice.getHiSyncId());
CachedBluetoothDevice mainDevice = findMainDevice(cachedDevice);
- if (mainDevice != null){
+ if (mainDevice != null) {
if (mainDevice.isConnected()) {
// When main device exists and in connected state, receiving sub device
// connection. To refresh main device UI
mainDevice.refresh();
- return true;
} else {
// When both Hearing Aid devices are disconnected, receiving sub device
// connection. To switch content and dispatch to notify UI change
@@ -207,9 +224,15 @@
// It is necessary to do remove and add for updating the mapping on
// preference and device
mBtManager.getEventManager().dispatchDeviceAdded(mainDevice);
- return true;
+ // Only need to set first device of a set. AudioDeviceInfo for
+ // GET_DEVICES_OUTPUTS will not change device.
+ setAudioRoutingConfig(cachedDevice);
}
+ return true;
}
+ // Only need to set first device of a set. AudioDeviceInfo for GET_DEVICES_OUTPUTS
+ // will not change device.
+ setAudioRoutingConfig(cachedDevice);
break;
case BluetoothProfile.STATE_DISCONNECTED:
mainDevice = findMainDevice(cachedDevice);
@@ -232,13 +255,83 @@
// It is necessary to do remove and add for updating the mapping on
// preference and device
mBtManager.getEventManager().dispatchDeviceAdded(cachedDevice);
+
return true;
}
+ // Only need to clear when last device of a set get disconnected
+ clearAudioRoutingConfig();
break;
}
return false;
}
+ private void setAudioRoutingConfig(CachedBluetoothDevice device) {
+ AudioDeviceAttributes hearingDeviceAttributes =
+ mRoutingHelper.getMatchedHearingDeviceAttributes(device);
+ if (hearingDeviceAttributes == null) {
+ Log.w(TAG, "Can not find expected AudioDeviceAttributes for hearing device: "
+ + device.getDevice().getAnonymizedAddress());
+ return;
+ }
+
+ final int callRoutingValue = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.HEARING_AID_CALL_ROUTING,
+ HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ final int mediaRoutingValue = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.HEARING_AID_MEDIA_ROUTING,
+ HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ final int ringtoneRoutingValue = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
+ HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ final int systemSoundsRoutingValue = Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
+ HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.CALL_ROUTING_ATTRIBUTES,
+ hearingDeviceAttributes, callRoutingValue);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES,
+ hearingDeviceAttributes, mediaRoutingValue);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE,
+ hearingDeviceAttributes, ringtoneRoutingValue);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES,
+ hearingDeviceAttributes, systemSoundsRoutingValue);
+ }
+
+ private void clearAudioRoutingConfig() {
+ // Don't need to pass hearingDevice when we want to reset it (set to AUTO).
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.CALL_ROUTING_ATTRIBUTES,
+ /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES,
+ /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE,
+ /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ setPreferredDeviceRoutingStrategies(
+ HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES,
+ /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+ }
+
+ private void setPreferredDeviceRoutingStrategies(int[] attributeSdkUsageList,
+ AudioDeviceAttributes hearingDevice,
+ @HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
+ final List<AudioProductStrategy> supportedStrategies =
+ mRoutingHelper.getSupportedStrategies(attributeSdkUsageList);
+
+ final boolean status = mRoutingHelper.setPreferredDeviceRoutingStrategies(
+ supportedStrategies, hearingDevice, routingValue);
+
+ if (!status) {
+ Log.w(TAG, "routingStrategies: " + supportedStrategies.toString() + "routingValue: "
+ + routingValue + " fail to configure AudioProductStrategy");
+ }
+ }
+
CachedBluetoothDevice findMainDevice(CachedBluetoothDevice device) {
for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
if (isValidHiSyncId(cachedDevice.getHiSyncId())) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index a3c2e70..43e3a32 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -361,6 +361,7 @@
cachedDevice.setHearingAidInfo(infoBuilder.build());
}
}
+
HearingAidStatsLogUtils.logHearingAidInfo(cachedDevice);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 071ab27..a9d15f3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -97,7 +97,7 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef({SelectionBehavior.SELECTION_BEHAVIOR_NONE,
- SELECTION_BEHAVIOR_TRANSFER,
+ SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER,
SelectionBehavior.SELECTION_BEHAVIOR_GO_TO_APP
})
public @interface SelectionBehavior {
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 f06623d..4b3820e 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
@@ -403,7 +403,7 @@
*/
@Test
public void updateHearingAidDevices_directToHearingAidDeviceManager() {
- mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mLocalBluetoothManager,
+ mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
mCachedDeviceManager.mCachedDevices));
mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
mCachedDeviceManager.updateHearingAidsDevices();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java
new file mode 100644
index 0000000..8b5ea30
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.audiopolicy.AudioProductStrategy;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/** Tests for {@link HearingAidAudioRoutingHelper}. */
+@RunWith(RobolectricTestRunner.class)
+public class HearingAidAudioRoutingHelperTest {
+
+ @Rule
+ public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
+ private static final String NOT_EXPECT_DEVICE_ADDRESS = "11:B2:B2:B2:B2:B2";
+
+ @Mock
+ private AudioProductStrategy mAudioStrategy;
+ @Spy
+ private AudioManager mAudioManager = mContext.getSystemService(AudioManager.class);
+ @Mock
+ private AudioDeviceInfo mAudioDeviceInfo;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private CachedBluetoothDevice mSubCachedBluetoothDevice;
+ private AudioDeviceAttributes mHearingDeviceAttribute;
+ private HearingAidAudioRoutingHelper mHelper;
+
+ @Before
+ public void setUp() {
+ doReturn(mAudioManager).when(mContext).getSystemService(AudioManager.class);
+ when(mAudioDeviceInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_HEARING_AID);
+ when(mAudioDeviceInfo.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+ when(mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).thenReturn(
+ new AudioDeviceInfo[]{mAudioDeviceInfo});
+ when(mAudioStrategy.getAudioAttributesForLegacyStreamType(
+ AudioManager.STREAM_MUSIC))
+ .thenReturn((new AudioAttributes.Builder()).build());
+
+ mHearingDeviceAttribute = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.TYPE_HEARING_AID,
+ TEST_DEVICE_ADDRESS);
+ mHelper = spy(new HearingAidAudioRoutingHelper(mContext));
+ doReturn(List.of(mAudioStrategy)).when(mHelper).getAudioProductStrategies();
+ }
+
+ @Test
+ public void setPreferredDeviceRoutingStrategies_valueAuto_callRemoveStrategy() {
+ mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
+ mHearingDeviceAttribute,
+ HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+
+ verify(mAudioManager, atLeastOnce()).removePreferredDeviceForStrategy(mAudioStrategy);
+ }
+
+ @Test
+ public void setPreferredDeviceRoutingStrategies_valueHearingDevice_callSetStrategy() {
+ mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
+ mHearingDeviceAttribute,
+ HearingAidAudioRoutingConstants.RoutingValue.HEARING_DEVICE);
+
+ verify(mAudioManager, atLeastOnce()).setPreferredDeviceForStrategy(mAudioStrategy,
+ mHearingDeviceAttribute);
+ }
+
+ @Test
+ public void setPreferredDeviceRoutingStrategies_valueDeviceSpeaker_callSetStrategy() {
+ final AudioDeviceAttributes speakerDevice = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
+ mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
+ mHearingDeviceAttribute,
+ HearingAidAudioRoutingConstants.RoutingValue.DEVICE_SPEAKER);
+
+ verify(mAudioManager, atLeastOnce()).setPreferredDeviceForStrategy(mAudioStrategy,
+ speakerDevice);
+ }
+
+ @Test
+ public void getMatchedHearingDeviceAttributes_mainHearingDevice_equalAddress() {
+ when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+ when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+
+ final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+ mCachedBluetoothDevice).getAddress();
+
+ assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+ }
+
+ @Test
+ public void getMatchedHearingDeviceAttributes_subHearingDevice_equalAddress() {
+ when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+ when(mCachedBluetoothDevice.getAddress()).thenReturn(NOT_EXPECT_DEVICE_ADDRESS);
+ when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mSubCachedBluetoothDevice);
+ when(mSubCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+ when(mSubCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+
+ final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+ mCachedBluetoothDevice).getAddress();
+
+ assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+ }
+
+ @Test
+ public void getMatchedHearingDeviceAttributes_memberHearingDevice_equalAddress() {
+ when(mSubCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+ when(mSubCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+ final Set<CachedBluetoothDevice> memberDevices = new HashSet<CachedBluetoothDevice>();
+ memberDevices.add(mSubCachedBluetoothDevice);
+ when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+ when(mCachedBluetoothDevice.getAddress()).thenReturn(NOT_EXPECT_DEVICE_ADDRESS);
+ when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(memberDevices);
+
+ final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+ mCachedBluetoothDevice).getAddress();
+
+ assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index 470d8e0..a839136 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -18,7 +18,12 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -29,18 +34,32 @@
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.audiopolicy.AudioProductStrategy;
import android.os.Parcel;
+import androidx.test.core.app.ApplicationProvider;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class HearingAidDeviceManagerTest {
+ @Rule
+ public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
private final static long HISYNCID1 = 10;
private final static long HISYNCID2 = 11;
private final static String DEVICE_NAME_1 = "TestName_1";
@@ -51,6 +70,15 @@
private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
private final BluetoothClass DEVICE_CLASS =
createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
+
+ private CachedBluetoothDevice mCachedDevice1;
+ private CachedBluetoothDevice mCachedDevice2;
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
+ private HearingAidDeviceManager mHearingAidDeviceManager;
+ private AudioDeviceAttributes mHearingDeviceAttribute;
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Spy
+ private HearingAidAudioRoutingHelper mHelper = new HearingAidAudioRoutingHelper(mContext);
@Mock
private LocalBluetoothProfileManager mLocalProfileManager;
@Mock
@@ -60,14 +88,12 @@
@Mock
private HearingAidProfile mHearingAidProfile;
@Mock
+ private AudioProductStrategy mAudioStrategy;
+ @Mock
private BluetoothDevice mDevice1;
@Mock
private BluetoothDevice mDevice2;
- private CachedBluetoothDevice mCachedDevice1;
- private CachedBluetoothDevice mCachedDevice2;
- private CachedBluetoothDeviceManager mCachedDeviceManager;
- private HearingAidDeviceManager mHearingAidDeviceManager;
- private Context mContext;
+
private BluetoothClass createBtClass(int deviceClass) {
Parcel p = Parcel.obtain();
@@ -81,8 +107,6 @@
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
@@ -94,10 +118,18 @@
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mAudioStrategy.getAudioAttributesForLegacyStreamType(
+ AudioManager.STREAM_MUSIC))
+ .thenReturn((new AudioAttributes.Builder()).build());
+ doReturn(List.of(mAudioStrategy)).when(mHelper).getSupportedStrategies(any(int[].class));
+ mHearingDeviceAttribute = new AudioDeviceAttributes(
+ AudioDeviceAttributes.ROLE_OUTPUT,
+ AudioDeviceInfo.TYPE_HEARING_AID,
+ DEVICE_ADDRESS_1);
mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
- mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mLocalBluetoothManager,
- mCachedDeviceManager.mCachedDevices));
+ mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
+ mCachedDeviceManager.mCachedDevices, mHelper));
mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
}
@@ -446,6 +478,44 @@
}
@Test
+ public void onProfileConnectionStateChanged_connected_callSetStrategies() {
+ when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
+ mHearingDeviceAttribute);
+
+ mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
+ BluetoothProfile.STATE_CONNECTED);
+
+ verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
+ eq(List.of(mAudioStrategy)), any(AudioDeviceAttributes.class), anyInt());
+ }
+
+ @Test
+ public void onProfileConnectionStateChanged_disconnected_callSetStrategiesWithAutoValue() {
+ when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
+ mHearingDeviceAttribute);
+
+ mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
+ BluetoothProfile.STATE_DISCONNECTED);
+
+ verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
+ eq(List.of(mAudioStrategy)), /* hearingDevice= */ isNull(),
+ eq(HearingAidAudioRoutingConstants.RoutingValue.AUTO));
+ }
+ @Test
+ public void onProfileConnectionStateChanged_unpairing_callSetStrategiesWithAutoValue() {
+ when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
+ mHearingDeviceAttribute);
+
+ when(mCachedDevice1.getUnpairing()).thenReturn(true);
+ mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
+ BluetoothProfile.STATE_DISCONNECTED);
+
+ verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
+ eq(List.of(mAudioStrategy)), /* hearingDevice= */ isNull(),
+ eq(HearingAidAudioRoutingConstants.RoutingValue.AUTO));
+ }
+
+ @Test
public void findMainDevice() {
when(mCachedDevice1.getHiSyncId()).thenReturn(HISYNCID1);
when(mCachedDevice2.getHiSyncId()).thenReturn(HISYNCID1);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 8b38deb..941697b 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -376,7 +376,7 @@
name: "SystemUIRobo-stub",
defaults: [
"platform_app_defaults",
- "SystemUI_app_defaults",
+ "SystemUI_optimized_defaults",
"SystemUI_compose_defaults",
],
manifest: "tests/AndroidManifest-base.xml",
@@ -443,7 +443,7 @@
}
systemui_optimized_java_defaults {
- name: "SystemUI_app_defaults",
+ name: "SystemUI_optimized_defaults",
soong_config_variables: {
SYSTEMUI_OPTIMIZE_JAVA: {
optimize: {
@@ -452,12 +452,10 @@
shrink: true,
shrink_resources: true,
proguard_compatibility: false,
- proguard_flags_files: ["proguard.flags"],
},
conditions_default: {
optimize: {
proguard_compatibility: false,
- proguard_flags_files: ["proguard.flags"],
},
},
},
@@ -468,7 +466,7 @@
name: "SystemUI",
defaults: [
"platform_app_defaults",
- "SystemUI_app_defaults",
+ "SystemUI_optimized_defaults",
],
static_libs: [
"SystemUI-core",
@@ -483,6 +481,9 @@
kotlincflags: ["-Xjvm-default=enable"],
dxflags: ["--multi-dex"],
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
required: [
"privapp_whitelist_com.android.systemui",
"wmshell.protolog.json.gz",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 650d5fa..09c62d0 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -235,7 +235,10 @@
<uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS" />
<uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+
+ <!-- role holder APIs -->
<uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
+ <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
<!-- It's like, reality, but, you know, virtual -->
<uses-permission android:name="android.permission.ACCESS_VR_MANAGER" />
@@ -344,9 +347,19 @@
<uses-permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" />
+ <!-- Intent Chooser -->
+ <permission
+ android:name="android.permission.ADD_CHOOSER_PINS"
+ android:protectionLevel="signature" />
+ <uses-permission android:name="android.permission.ADD_CHOOSER_PINS" />
+ <permission
+ android:name="android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
+ android:protectionLevel="signature" />
+
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
+ <protected-broadcast android:name="com.android.systemui.action.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG" />
<protected-broadcast android:name="com.android.systemui.STARTED" />
<application
@@ -632,12 +645,6 @@
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true">
</activity>
- <activity-alias
- android:name=".UsbDebuggingActivityAlias"
- android:permission="android.permission.DUMP"
- android:targetActivity=".usb.UsbDebuggingActivity"
- android:exported="true">
- </activity-alias>
<activity android:name=".usb.UsbDebuggingSecondaryUserActivity"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
@@ -925,7 +932,7 @@
android:showForAllUsers="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
- android:configChanges="screenLayout|keyboard|keyboardHidden|orientation"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden|orientation"
android:visibleToInstantApps="true">
</activity>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml
new file mode 100644
index 0000000..d25970c
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-af/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Toeganklikheid- kieslys"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Die Toeganklikheidkieslys bied ’n groot kieslys op die skerm om jou toestel te beheer. Jy kan jou toestel sluit, volume en helderheid beheer, skermskote neem, en meer."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistent"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Toeganklikheidinstellings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volumekontroles"</string>
+ <string name="power_label" msgid="7699720321491287839">"Krag"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Kragopsies"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Onlangse programme"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Sluitskerm"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Kitsinstellings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Kennisgewings"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skermkiekie"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Neem skermkiekie"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume harder"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume sagter"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Verhoog helderheid"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Verlaag helderheid"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Gaan na vorige skerm toe"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Gaan na volgende skerm toe"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Die Toeganklikheidkieslys bied ’n groot kieslys op die skerm om jou toestel te beheer. Jy kan jou toestel sluit, volume en helderheid beheer, skermskote neem, en meer."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Beheer toestel deur groot kieslys"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Toeganklikheidkieslys-instellings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Groot knoppies"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Maak Toeganklikheidkieslys-knoppies groter"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hulp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Helderheid <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musiekvolume <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml
new file mode 100644
index 0000000..fa18989
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-am/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"የተደራሽነት ምናሌ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገጽ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገጽ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"ረዳት"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"የተደራሽነት ቅንብሮች"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ድምፅ"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"የድምጽ መቆጣጠሪያዎች"</string>
+ <string name="power_label" msgid="7699720321491287839">"ኃይል"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"የኃይል አማራጮች"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"የቅርብ ጊዜ መተግበሪያዎች"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ማያ ገጽ ቁልፍ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ፈጣን ቅንብሮች"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ማሳወቂያዎች"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ቅጽበታዊ ገጽ እይታ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ድምፅ ጨምር"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ድምፅ ቀንስ"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ብሩህነት ጨምር"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ብሩህነት ቀንስ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ወደ ቀዳሚው ማያ ገጽ ይሂዱ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ወደ ቀጣዩ ማያ ገጽ ይሂዱ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"የተደራሽነት ምናሌ መሣሪያዎን ለመቆጣጠር ትልቅ የማያ ገጽ ላይ ምናሌን ያቀርባል። የእርስዎን መሣሪያ መቆለፍ፣ ድምፅን እና ብሩህነትን መቆጣጠር፣ ቅጽበታዊ ገጽ ዕይታዎችን ማንሳት እና ተጨማሪ ነገሮችን ማድረግ ይችላሉ።"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"መሣሪያውን በትልቅ ምናሌ በኩል ይቆጣጠሩ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"የተደራሽነት ምናሌ ቅንብሮች"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ትልቅ አዝራሮች"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"የተደራሽነት ምናሌ አዝራሮች መጠን ይጨምሩ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"እገዛ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"የብርሃን መጠን <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"የሙዚቃ ድምፅ መጠን<xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ar/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ar/strings.xml
new file mode 100644
index 0000000..89e42a3
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ar/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"قائمة \"تسهيل الاستخدام\""</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"قائمة \"تسهيل الاستخدام\" هي قائمة كبيرة تظهر على الشاشة وتتيح لك التحكّم في جهازك. يمكنك من خلال هذه القائمة قفل جهازك والتحكّم في مستوى الصوت والسطوع وتسجيل لقطات الشاشة وغير ذلك."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"مساعِد"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"إعدادات \"سهولة الاستخدام\""</string>
+ <string name="volume_label" msgid="3682221827627150574">"مستوى الصوت"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"عناصر التحكم في مستوى الصوت"</string>
+ <string name="power_label" msgid="7699720321491287839">"زر التشغيل"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"خيارات التشغيل"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"التطبيقات المستخدمة مؤخرًا"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"شاشة القفل"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"الإعدادات السريعة"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"الإشعارات"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"لقطة شاشة"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"أخذ لقطة شاشة"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"رفع الصوت"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"خفض الصوت"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"رفع مستوى السطوع"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"خفض مستوى السطوع"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"الانتقال إلى الشاشة السابقة"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"الانتقال إلى الشاشة التالية"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"توفّر قائمة \"تسهيل الاستخدام\" قائمةً كبيرةً تُعرض على الشاشة تتيح لك الحكّم في جهازك. يمكنك من خلال هذه القائمة قفل جهازك أو التحكّم في مستوى الصوت والسطوع وتسجيل لقطات الشاشة وغير ذلك."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"التحكُّم في جهازك من خلال قائمة كبيرة الحجم"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"إعدادات قائمة \"سهولة الاستخدام\""</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"الأزرار الكبيرة"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"زيادة حجم أزرار قائمة \"سهولة الاستخدام\""</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"مساعدة"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"السطوع <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"مستوى صوت الموسيقى <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-as/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-as/strings.xml
new file mode 100644
index 0000000..0528f39
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-as/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"সাধ্য সুবিধাসমূহৰ মেনু"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"সাধ্য সুবিধাৰ মেনুখনে আপোনাৰ ডিভাইচটো নিয়ন্ত্ৰণ কৰিবলৈ স্ক্ৰীনত এখন ডাঙৰ মেনু দেখুৱায়। আপুনি নিজৰ ডিভাইচটো লক কৰিব পাৰে, ভলিউম আৰু উজ্জ্বলতা নিয়ন্ত্ৰণ কৰিব পাৰে, স্ক্ৰীনশ্বট ল’ব পাৰে আৰু বহুতো কাম কৰিব পাৰে।"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"সাধ্য সুবিধাৰ ছেটিং"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ভলিউম"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ভলিউমৰ নিয়ন্ত্ৰণসমূহ"</string>
+ <string name="power_label" msgid="7699720321491287839">"অন/অফ"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"অন/অফ বুটামৰ বিকল্পসমূহ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"শেহতীয়া এপসমূহ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"লক স্ক্ৰীন"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ক্ষিপ্ৰ ছেটিং"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"জাননীসমূহ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"স্ক্ৰীণশ্বট"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"স্ক্ৰীণশ্বট লওক"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ভলিউম বঢ়াওক"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ভলিউম কমাওক"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"উজ্জ্বলতা বঢ়াওক"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"উজ্জ্বলতা কমাওক"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"পূৰ্বৱৰ্তী স্ক্ৰীনখনলৈ যাওক"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"পৰৱৰ্তী স্ক্ৰীনখনলৈ যাওক"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"সাধ্য সুবিধা মেনুৱে আপোনাৰ ডিভাইচটো নিয়ন্ত্ৰণ কৰিবলৈ স্ক্ৰীনত এখন বৃহৎ মেনু দেখুৱায়। আপুনি নিজৰ ডিভাইচটো লক কৰিব পাৰে, ভলিউম আৰু উজ্জ্বলতা নিয়ন্ত্ৰণ কৰিব পাৰে, স্ক্ৰীনশ্বট ল’ব পাৰে আৰু লগতে বহুতো কাম কৰিব পাৰে।"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ডাঙৰ মেনুৰ জৰিয়তে ডিভাইচ নিয়ন্ত্ৰণ কৰক"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"সাধ্য সুবিধা মেনুৰ ছেটিং"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ডাঙৰ বুটাম"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"সাধ্য সুবিধাৰ মেনু বুটামবিলাকৰ আকাৰ বঢ়াওক"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"সহায়"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"উজ্জ্বলতা <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"সংগীতৰ ভলিউম <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-az/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-az/strings.xml
new file mode 100644
index 0000000..f366f3d
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-az/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Əlçatımlılıq Menyusu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Əlçatımlılıq Menyusu cihazınızı idarə etmək üçün böyük geniş ekran menyusu təqdim edir. Cihazı kilidləyə, səs səviyyəsinə və parlaqlığa nəzarət edə, skrinşotlar çəkə və s. edə bilərsiniz."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Əlçatımlılıq Ayarları"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Səs"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Səs nəzarətləri"</string>
+ <string name="power_label" msgid="7699720321491287839">"Yandırıb-söndürmə düyməsi"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Qidalanma düyməsi seçimləri"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Son tətbiqlər"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ekran kilidi"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Sürətli Ayarlar"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Bildirişlər"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skrinşot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Skrinşot çəkin"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Səsi artırın"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Səsi azaldın"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Parlaqlığı artırın"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Parlaqlığı azaldın"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Əvvəlki ekrana keçin"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Növbəti ekrana keçin"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Əlçatımlılıq Menyusu cihazınızı idarə etmək üçün böyük geniş ekran menyusu təqdim edir. Cihazı kilidləyə, səs səviyyəsinə və parlaqlığa nəzarət edə, skrinşotlar çəkə və s. edə bilərsiniz."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Cihazı böyük menyu ilə idarə edin"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Əlçatımlılıq Menyusu Ayarları"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Böyük düymələr"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Əlçatımlıq Menyusu Düymələrinin ölçüsünü artırın"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Yardım"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Parlaqlıq <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musiqinin səs həcmi <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..fa2ca24
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Meni Pristupačnost"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Meni Pristupačnost pruža veliki meni na ekranu za kontrolu uređaja. Možete da zaključate uređaj, kontrolišete jačinu zvuka i osvetljenost, pravite snimke ekrana i drugo."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Pomoćnik"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Podešavanja pristupačnosti"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Jačina zvuka"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrole jačine zvuka"</string>
+ <string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaključan ekran"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Brza podešavanja"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Obaveštenja"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Snimak ekrana"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Snimi ekran"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Pojačaj zvuk"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Utišaj zvuk"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Povećajte osvetljenost"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Smanjite osvetljenost"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Idi na prethodni ekran"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Idi na sledeći ekran"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Meni Pristupačnost pruža veliki meni na ekranu za kontrolu uređaja. Možete da zaključate uređaj, kontrolišete jačinu zvuka i osvetljenost, pravite snimke ekrana i drugo."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrolišite uređaj pomoću velikog menija"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Podešavanja menija Pristupačnost"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Velika dugmad"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećajte veličinu dugmadi u meniju za pristupačnost"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomoć"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Osvetljenost: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Jačina zvuka muzike: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml
new file mode 100644
index 0000000..53ce5fa
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Спецыяльныя магчымасці"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Меню спецыяльных магчымасцей – гэта вялікае экраннае меню для кіравання прыладай. Вы можаце блакіраваць прыладу, рэгуляваць гучнасць і яркасць, рабіць здымкі экрана і выконваць іншыя дзеянні."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Памочнік"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Налады спецыяльных магчымасцей"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Гучнасць"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Рэгулятары гучнасці"</string>
+ <string name="power_label" msgid="7699720321491287839">"Кнопка сілкавання"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Налады кнопкі сілкавання"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Нядаўнія праграмы"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Экран блакіроўкі"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Хуткія налады"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Апавяшчэнні"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Здымак экрана"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Зрабіць здымак экрана"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Павялічыць гучнасць"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Паменшыць гучнасць"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Павялічыць яркасць"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Паменшыць яркасць"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Вярнуцца на папярэдні экран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Перайсці на наступны экран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Меню спецыяльных магчымасцей – гэта вялікае экраннае меню для кіравання прыладай. Вы можаце блакіраваць прыладу, рэгуляваць гучнасць і яркасць, рабіць здымкі экрана і выконваць іншыя дзеянні."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Кіраваць прыладай праз вялікае меню"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Налады меню спец. магчым."</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Вялікія кнопкі"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Павялічыць памер кнопак меню спецыяльных магчымасцей"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Даведка"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Яркасць: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Гучнасць музыкі: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bg/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bg/strings.xml
new file mode 100644
index 0000000..709a6e0
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bg/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Меню за достъпност"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Менюто за достъпност предоставя голямо екранно меню за управление на устройството ви. Можете да заключвате устройството си, да управлявате яркостта и силата на звука, да правите екранни снимки и др."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Асистент"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Асистент"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Настройки за достъпност"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Сила на звука"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Контроли за силата на звука"</string>
+ <string name="power_label" msgid="7699720321491287839">"Захранване"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Опции за захранването"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Скорошни приложения"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Заключен екран"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Бързи настройки"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Известия"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Екранна снимка"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Създава екранни снимки"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Увеличаване на силата на звука"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Намаляване на силата на звука"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Увеличаване на яркостта"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Намаляване на яркостта"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Към предишния екран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Към следващия екран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Менюто за достъпност предоставя голямо екранно меню за управление на устройството ви. Можете да заключвате устройството си, да управлявате яркостта и силата на звука, да правите екранни снимки и др."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Управление на устройството чрез голямо меню"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Настр. за меню за дост."</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Големи бутони"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Увеличаване на размера на бутоните в менюто за достъпност"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Помощ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Яркост: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Сила на звука за музиката: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
new file mode 100644
index 0000000..b5d6593
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"অ্যাক্সেসিবিলিটি মেনু"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"আপনার ডিভাইস নিয়ন্ত্রণ করতে, \'অ্যাক্সেসিবিলিটি মেনু\' একটি বড় অন-স্ক্রিন মেনু দেখায়। আপনি ফোন লক, ভলিউম ও উজ্জ্বলতা নিয়ন্ত্রণ, স্ক্রিনশট নেওয়া এবং আরও অনেক কিছু করতে পারবেন।"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"অ্যাক্সেসিবিলিটি সেটিংস"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ভলিউম"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ভলিউম নিয়ন্ত্রণ"</string>
+ <string name="power_label" msgid="7699720321491287839">"পাওয়ার"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"পাওয়ারের বিকল্পগুলি"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"সাম্প্রতিক অ্যাপ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"লক স্ক্রিন"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"দ্রুত সেটিংস"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"বিজ্ঞপ্তি"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"স্ক্রিনশট"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"স্ক্রিনশট নিন"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ভলিউম বাড়ান"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ভলিউম কমান"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"উজ্জ্বলতা বাড়ান"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"উজ্জ্বলতা কমান"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"আগের স্ক্রিনে যান"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"পরের স্ক্রিনে যান"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"আপনার ডিভাইস নিয়ন্ত্রণ করতে, \'অ্যাক্সেসিবিলিটি মেনু\' একটি বড় অন-স্ক্রিন মেনু দেখায়। আপনি ফোন লক, ভলিউম ও উজ্জ্বলতা নিয়ন্ত্রণ, স্ক্রিনশট নেওয়া এবং আরও অনেক কিছু করতে পারবেন।"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"বড় করে দেখানো মেনুর মাধ্যমে ডিভাইস নিয়ন্ত্রণ করুন"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"অ্যাক্সেসিবিলিটি মেনুর সেটিংস"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"বোতাম বড় করা"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"অ্যাক্সেসিবিলিটি মেনু বোতামের সাইজ বাড়ান"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"সহায়তা"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"উজ্জ্বলতা <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"মিউজিকের ভলিউম <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
new file mode 100644
index 0000000..227186b
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Meni za pristupačnost"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Meni za pristupačnost pruža veliki meni na ekranu za upravljanje uređajem. Možete zaključati uređaj, kontrolirati jačinu zvuka i osvjetljenje, praviti snimke ekrana i drugo."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Asistent"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Postavke pristupačnosti"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Jačina zvuka"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrole jačine zvuka"</string>
+ <string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaključavanje ekrana"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Brze postavke"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Obavještenja"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Snimak ekrana"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Napravi snimak ekrana"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Pojačaj zvuk"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Utišaj zvuk"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Jače osvjetljenje"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Slabije osvjetljenje"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Idi na prethodni ekran"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Idi na sljedeći ekran"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Meni za pristupačnost pruža veliki meni na ekranu za upravljanje uređajem. Možete zaključati uređaj, kontrolirati jačinu zvuka i osvjetljenje, praviti snimke ekrana i drugo."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Upravljajte uređajem putem velikog menija"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke Menija za pristupačnost"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Velika dugmad"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećajte dugmad menija za pristupačnost"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomoć"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Osvjetljenje: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Jačina zvuka muzike: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ca/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ca/strings.xml
new file mode 100644
index 0000000..08a301c
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ca/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menú d\'accessibilitat"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"El menú d\'accessibilitat t\'ofereix un menú gran en pantalla perquè controlis el dispositiu. Pots bloquejar-lo, controlar-ne el volum i la brillantor, fer captures de pantalla i molt més."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Configuració d\'accessibilitat"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volum"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controls de volum"</string>
+ <string name="power_label" msgid="7699720321491287839">"Botó d\'engegada"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcions d\'engegada"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplicacions recents"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Pantalla de bloqueig"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Configuració ràpida"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificacions"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de pantalla"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Fes una captura de pantalla"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Apuja el volum"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Abaixa el volum"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Augmenta la brillantor"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Disminueix la brillantor"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ves a la pantalla anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ves a la pantalla següent"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"El menú d\'accessibilitat t\'ofereix un menú gran en pantalla perquè controlis el dispositiu. Pots bloquejar-lo, controlar-ne el volum i la brillantor, fer captures de pantalla i molt més."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controla el dispositiu amb un menú gran"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Config. del menú d\'accessibilitat"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botons grans"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenta la mida dels botons del menú d\'accessibilitat"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ajuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brillantor: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volum de la música: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml
new file mode 100644
index 0000000..796a3d5
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-cs/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Nabídka usnadnění přístupu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Nabídka usnadnění přístupu zobrazuje na obrazovce velkou nabídku k ovládání zařízení. Můžete zamknout zařízení, upravit hlasitost a jas, pořídit snímek obrazovky apod."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Asistent"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Nastavení usnadnění přístupu"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Hlasitost"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Ovládání hlasitosti"</string>
+ <string name="power_label" msgid="7699720321491287839">"Vypínač"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Možnosti napájení"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Poslední aplikace"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Obrazovka uzamčení"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Rychlé nastavení"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Oznámení"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Snímek obrazovky"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Pořídit snímek obrazovky"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Zvýšit hlasitost"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Snížit hlasitost"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Zvýšit jas"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Snížit jas"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Zpět na předchozí obrazovku"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Přejít na další obrazovku"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Nabídka usnadnění přístupu zobrazuje na obrazovce velkou nabídku k ovládání zařízení. Můžete zamknout zařízení, upravit hlasitost a jas, pořídit snímek obrazovky apod."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládejte zařízení pomocí velké nabídky"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavení nabídky usnadnění přístupu"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Velká tlačítka"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zvětšit tlačítka v nabídce přístupnosti"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Nápověda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Jas <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Hlasitost hudby <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-da/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-da/strings.xml
new file mode 100644
index 0000000..6cde7a1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-da/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menuen Hjælpefunktioner"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menuen Hjælpefunktioner giver dig en stor menu på skærmen, som du kan bruge til at styre din enhed. Du kan låse din enhed, justere lyd- og lysstyrken, tage screenshots og meget mere."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Indstillinger for hjælpefunktioner"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Lydstyrke"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Lydstyrkeknapper"</string>
+ <string name="power_label" msgid="7699720321491287839">"Afbryderknap"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Indstillinger for afbryderknappen"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Seneste apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lås skærm"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Kvikmenu"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifikationer"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Tag et screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Lydstyrke op"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Lydstyrke ned"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Lysstyrke op"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Lysstyrke ned"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Gå til forrige skærm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Gå til næste skærm"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menuen Hjælpefunktioner giver dig en stor menu på skærmen, som bruges til at styre din enhed. Du kan låse din enhed, justere lyd- og lysstyrken, tage screenshots og meget mere."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Styr enheden via den store menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Indstillinger for menuen Hjælpefunktioner"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Store knapper"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Forstør knapperne i menuen Hjælpefunktioner"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hjælp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Lysstyrke <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Lydstyrke for musik <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml
new file mode 100644
index 0000000..7b94d98
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-de/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menü für Bedienungshilfen"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Über das Menü „Bedienungshilfen“ lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Einstellungen für Bedienungshilfen"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Lautstärke"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Lautstärketasten"</string>
+ <string name="power_label" msgid="7699720321491287839">"Ein/Aus"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Optionen für Ein-/Aus-Taste"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Kürzlich geöffnete Apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Sperrbildschirm"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Schnelleinstellungen"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Benachrichtigungen"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Screenshot erstellen"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Lautstärke erhöhen"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Lautstärke verringern"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Helligkeit erhöhen"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Helligkeit verringern"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Zum vorherigen Bildschirm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Zum nächsten Bildschirm"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Über das Menü „Bedienungshilfen“ lässt sich ein großes Menü zur Bedienung deines Geräts auf dem Bildschirm öffnen. Du kannst beispielsweise das Gerät sperren, die Lautstärke und Helligkeit anpassen und Screenshots machen."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Gerät mit großem Menü steuern"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Menüeinstellungen für Bedienungshilfen"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Große Schaltflächen"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Schaltflächen für das Menü \"Bedienungshilfen\" vergrößern"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hilfe"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Helligkeit: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musiklautstärke: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml
new file mode 100644
index 0000000..e5f7cd4
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Μενού προσβασιμότητας"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Το μενού προσβασιμότητας παρέχει ένα μεγάλο μενού στην οθόνη για να ελέγχετε τη συσκευή σας. Μπορείτε να κλειδώνετε τη συσκευή, να ελέγχετε την ένταση ήχου και τη φωτεινότητα, να λαμβάνετε στιγμιότυπα οθόνης και άλλα."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Βοηθός"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Ρυθμίσεις προσβασιμότητας"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Ένταση"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Πλήκτρα έντασης ήχου"</string>
+ <string name="power_label" msgid="7699720321491287839">"Κουμπί λειτουργίας"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Επιλογές λειτουργίας"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Πρόσφατες εφαρμογές"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Κλείδωμα οθόνης"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Γρήγορες ρυθμίσεις"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Ειδοποιήσεις"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Στιγμιότυπο οθόνης"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Λήψη στιγμιότυπου οθόνης"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Αύξηση έντασης ήχου"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Μείωση έντασης ήχου"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Αύξηση φωτεινότητας"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Μείωση φωτεινότητας"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Μετάβαση στην προηγούμενη οθόνη"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Μετάβαση στην επόμενη οθόνη"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Το μενού προσβασιμότητας παρέχει ένα μεγάλο μενού στην οθόνη για να ελέγχετε τη συσκευή σας. Μπορείτε να κλειδώνετε τη συσκευή, να ελέγχετε την ένταση ήχου και τη φωτεινότητα, να λαμβάνετε στιγμιότυπα οθόνης και άλλα."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Έλεγχος συσκευής μέσω μεγάλου μενού"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Ρυθμίσεις μενού προσβασιμότητας"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Μεγάλα κουμπιά"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Αύξηση του μεγέθους των κουμπιών στο μενού προσβασιμότητας"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Βοήθεια"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Φωτεινότητα <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Ένταση μουσικής <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rAU/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..04b18dd
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rAU/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Accessibility menu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibility Settings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volume controls"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Power options"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recent apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Quick Settings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Take screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume up"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume down"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Brightness up"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Brightness down"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Go to previous screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Go to next screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Control device via large menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Accessibility Menu Settings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Large buttons"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Increase size of Accessibility Menu Buttons"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Help"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brightness <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Music volume <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rCA/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..2b300620
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rCA/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Accessibility Menu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"The Accessibility Menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots, and more."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibility Settings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volume controls"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Power options"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recent apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Quick Settings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Take screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume up"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume down"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Brightness up"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Brightness down"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Go to previous screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Go to next screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"The Accessibility Menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots, and more."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Control device via large menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Accessibility Menu Settings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Large buttons"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Increase size of Accessibility Menu Buttons"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Help"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brightness <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Music volume <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rGB/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..04b18dd
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rGB/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Accessibility menu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibility Settings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volume controls"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Power options"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recent apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Quick Settings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Take screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume up"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume down"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Brightness up"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Brightness down"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Go to previous screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Go to next screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Control device via large menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Accessibility Menu Settings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Large buttons"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Increase size of Accessibility Menu Buttons"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Help"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brightness <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Music volume <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rIN/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..04b18dd
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rIN/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Accessibility menu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibility Settings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volume controls"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Power options"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recent apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Quick Settings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Take screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume up"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume down"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Brightness up"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Brightness down"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Go to previous screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Go to next screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"The Accessibility menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots and more."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Control device via large menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Accessibility Menu Settings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Large buttons"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Increase size of Accessibility Menu Buttons"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Help"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brightness <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Music volume <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rXC/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..8ab2c52
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-en-rXC/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Accessibility Menu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"The Accessibility Menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots, and more."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibility Settings"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volume controls"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Power options"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recent apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Quick Settings"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Take screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume up"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume down"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Brightness up"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Brightness down"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Go to previous screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Go to next screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"The Accessibility Menu provides a large on-screen menu to control your device. You can lock your device, control volume and brightness, take screenshots, and more."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Control device via large menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Accessibility Menu Settings"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Large buttons"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Increase size of Accessibility Menu Buttons"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Help"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brightness <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Music volume <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-es-rUS/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..f7628eb
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-es-rUS/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menú de Accesibilidad"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"El menú de Accesibilidad es un menú de gran tamaño que se muestra en la pantalla y te permite controlar tu dispositivo. Puedes bloquearlo, controlar el volumen y el brillo, realizar capturas de pantalla y mucho más."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistente"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Configuración de accesibilidad"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volumen"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controles de volumen"</string>
+ <string name="power_label" msgid="7699720321491287839">"Encendido"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opciones de encendido"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Apps recientes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Pantalla de bloqueo"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Configuración rápida"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificaciones"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de pantalla"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Tomar captura de pantalla"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Subir volumen"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Bajar volumen"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar brillo"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Disminuir brillo"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir a la pantalla anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir a la siguiente pantalla"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"El menú de Accesibilidad es un menú de gran tamaño que se muestra en la pantalla y te permite controlar tu dispositivo. Puedes bloquearlo, controlar el volumen y el brillo, realizar capturas de pantalla y mucho más."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlar el dispositivo mediante el menú ampliado"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Configuración del menú de accesibilidad"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botones grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumenta el tamaño de los botones del menú de accesibilidad"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ayuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brillo: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volumen de la música: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-es/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-es/strings.xml
new file mode 100644
index 0000000..50c93f7
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-es/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menú de accesibilidad"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"El menú de accesibilidad es un menú de gran tamaño que se muestra en pantalla para controlar tu dispositivo. Puedes bloquear el dispositivo, controlar el volumen y el brillo, hacer capturas de pantalla y más."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistente"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Ajustes de accesibilidad"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volumen"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controles de volumen"</string>
+ <string name="power_label" msgid="7699720321491287839">"Encender"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opciones de encendido"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplicaciones recientes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Pantalla de bloqueo"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Ajustes rápidos"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificaciones"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de pantalla"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Hacer captura"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Subir volumen"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Bajar volumen"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar el brillo"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Reducir el brillo"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir a la pantalla anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir a la siguiente pantalla"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"El menú de accesibilidad es un menú de gran tamaño que se muestra en pantalla para controlar tu dispositivo. Puedes bloquear el dispositivo, controlar el volumen y el brillo, hacer capturas de pantalla y más."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controla el dispositivo con un menú de gran tamaño"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Ajustes del menú de accesibilidad"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botones grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumentar el tamaño de los botones del menú de accesibilidad"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ayuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brillo: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volumen de la música: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-et/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-et/strings.xml
new file mode 100644
index 0000000..790d060
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-et/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Juurdepääsetavuse menüü"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Juurdepääsetavuse menüü on suur ekraanil kuvatav menüü, mille abil oma seadet hallata. Saate oma seadme lukustada, hallata helitugevust ja heledust, jäädvustada ekraanipilte ning teha muudki."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Juurdepääsetavuse seaded"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Helitugevus"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Helitugevuse juhtnupud"</string>
+ <string name="power_label" msgid="7699720321491287839">"Toitenupp"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Toitevalikud"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Hiljutised rakendused"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lukustuskuva"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Kiirseaded"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Märguanded"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Ekraanipilt"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Jäädvusta ekraanipilt"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Suurenda helitugevust"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Vähenda helitugevust"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Suurenda eredust"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Vähenda eredust"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Eelmise ekraanikuva avamine"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Järgmise ekraanikuva avamine"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Juurdepääsetavuse menüü on suur ekraanil kuvatav menüü, mille abil oma seadet hallata. Saate oma seadme lukustada, hallata helitugevust ja heledust, jäädvustada ekraanipilte ning teha muudki."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Seadme juhtimine suure menüü kaudu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Juurdepääsetavuse menüü seaded"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Suured nupud"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Juurdepääsetavusmenüü nuppude suuruse suurendamine"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Abi"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Eredus on <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Muusika helitugevus on <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-eu/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-eu/strings.xml
new file mode 100644
index 0000000..98c0146
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-eu/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Erabilerraztasun-menua"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Erabilerraztasun-menuari esker, tamaina handiko menu bat izango duzu pantailan; menu horren bidez, gailua kontrolatzeko aukera izango duzu. Besteak beste, hauek egin ahalko dituzu: gailua blokeatu; bolumena eta distira kontrolatu, eta pantaila-argazkiak egin."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Laguntzailea"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Erabilerraztasun-ezarpenak"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Bolumena"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Bolumena kontrolatzeko aukerak"</string>
+ <string name="power_label" msgid="7699720321491287839">"Bateria"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Bateria kontrolatzeko aukerak"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Azken aplikazioak"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Pantaila blokeatua"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Ezarpen bizkorrak"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Jakinarazpenak"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Pantaila-argazkia"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Atera pantaila-argazki bat"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Igo bolumena"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Jaitsi bolumena"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Handitu distira"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Txikitu distira"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Joan aurreko pantailara"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Joan hurrengo pantailara"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Erabilerraztasun-menuari esker, tamaina handiko menu bat izango duzu pantailan; menu horren bidez, gailua kontrolatzeko aukera izango duzu. Besteak beste, hauek egin ahalko dituzu: gailua blokeatu; bolumena eta distira kontrolatu, eta pantaila-argazkiak egin."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrolatu gailua menu handiaren bidez"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Erabilerraztasun-menuaren ezarpenak"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botoi handiak"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Handitu erabilerraztasun-menuko botoien tamaina"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Laguntza"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Distira: %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musikaren bolumena: %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml
new file mode 100644
index 0000000..c922b24
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fa/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"منوی دسترسپذیری"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"«منوی دسترسپذیری» منوی بزرگی را روی صفحه برای کنترل دستگاه ارائه میدهد. میتوانید دستگاه را قفل کنید، میزان صدا و روشنایی را کنترل کنید، نماگرفت ثبت کنید، و کارهای بیشتری انجام دهید."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"دستیار"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"تنظیمات دسترسپذیری"</string>
+ <string name="volume_label" msgid="3682221827627150574">"میزان صدا"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"کنترلهای میزان صدا"</string>
+ <string name="power_label" msgid="7699720321491287839">"نیرو"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"گزینههای نیرو"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"برنامههای اخیر"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"صفحه قفل"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"تنظیمات سریع"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"اعلانها"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"نماگرفت"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"گرفتن نماگرفت"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"افزایش صدا"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"کاهش صدا"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"افزایش روشنایی"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"کاهش روشنایی"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"رفتن به صفحه قبل"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"رفتن به صفحه بعد"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"«منوی دسترسپذیری» منوی بزرگی را روی صفحه برای کنترل دستگاه ارائه میدهد. میتوانید دستگاه را قفل کنید، میزان صدا و روشنایی را کنترل کنید، نماگرفت ثبت کنید، و کارهای بیشتری انجام دهید."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"کنترل دستگاه ازطریق منوی بزرگ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"تنظیمات منوی دسترسپذیری"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"دکمههای بزرگ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"افزایش اندازه «دکمههای منوی دسترسپذیری»"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"راهنما"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"روشنایی <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"بلندی صدای موسیقی <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml
new file mode 100644
index 0000000..b9926a5
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fi/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Saavutettavuusvalikko"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Saavutettavuusvalikko on suuri näyttövalikko, josta voit ohjata laitettasi. Voit esimerkiksi lukita laitteen, säätää äänenvoimakkuutta ja kirkkautta sekä ottaa kuvakaappauksia."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Esteettömyysasetukset"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Äänenvoimakkuus"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Äänenvoimakkuuden hallinta"</string>
+ <string name="power_label" msgid="7699720321491287839">"Virta"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Virta-asetukset"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Viimeaikaiset sovellukset"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lukitusnäyttö"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Pika-asetukset"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Ilmoitukset"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Kuvakaappaus"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ota kuvakaappaus"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Lisää äänenvoimakkuutta"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Vähennä äänenvoimakkuutta"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Lisää kirkkautta"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Vähennä kirkkautta"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Siirry edelliselle näytöllä"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Siirry seuraavalle näytölle"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Saavutettavuusvalikko on suuri näyttövalikko, josta voit ohjata laitettasi. Voit esimerkiksi lukita laitteen, säätää äänenvoimakkuutta ja kirkkautta sekä ottaa kuvakaappauksia."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Ohjaa laitetta suurella valikolla"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Esteettömyysvalikon asetukset"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Suuret painikkeet"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Suurenna esteettömyysvalikon painikkeita"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ohje"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Kirkkaus <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musiikin äänenvoimakkuus <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..9ac0f041
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu d\'accessibilité"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu Accessibilité propose un grand espace à l\'écran à l\'aide duquel vous pouvez contrôler votre appareil. Utilisez-le pour verrouiller votre appareil, régler le volume et la luminosité, prendre des captures d\'écran et plus."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Paramètres d\'accessibilité"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Commandes de volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Alimentation"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Options d\'alimentation"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Applis récentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Écran verrouillage"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Paramètres rapides"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Capture d\'écran"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Prendre une capture d\'écran"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Augmenter volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Baisser volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Augmenter luminosité"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Baisser luminosité"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Aller à l\'écran précédent"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Aller à l\'écran suivant"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu Accessibilité propose un grand espace à l\'écran à l\'aide duquel vous pouvez contrôler votre appareil. Utilisez-le pour verrouiller votre appareil, régler le volume et la luminosité, prendre des captures d\'écran et plus."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôlez l\'appareil à l\'aide d\'un menu de grande taille"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu d\'accessibilité"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenter la taille des boutons du menu d\'accessibilité"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Aide"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Luminosité : <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume de la musique : <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
new file mode 100644
index 0000000..774210d
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu d\'accessibilité"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibilité"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Commandes de volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Marche/Arrêt"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Options du bouton Marche/Arrêt"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Applis récentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Écran de verrouillage"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Réglages rapides"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifications"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Capture d\'écran"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Prendre une capture d\'écran"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Augmenter volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Baisser volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Augmenter luminosité"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Baisser luminosité"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Revenir à l\'écran précédent"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Accéder à l\'écran suivant"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôlez votre appareil via un grand menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu d\'accessibilité"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenter la taille des boutons du menu d\'accessibilité"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Aide"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Luminosité : <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume de la musique : <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-gl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-gl/strings.xml
new file mode 100644
index 0000000..4d6656b
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-gl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menú de accesibilidade"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"O menú de accesibilidade é un panel grande que aparece na pantalla co que podes controlar o dispositivo. Permíteche realizar varias accións, entre elas, bloquear o dispositivo, controlar o volume, axustar o brillo e facer capturas de pantalla."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistente"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Accesibilidade (configuración)"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controis de volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Acender"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcións de acendido"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplicacións recentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Pantalla de bloqueo"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Configuración rápida"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificacións"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de pantalla"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Fai unha captura de pantalla"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Subir volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Baixar volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar brillo"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Reducir brillo"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir á pantalla anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir á seguinte pantalla"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"O menú de accesibilidade é un panel grande que aparece na pantalla e permite controlar o dispositivo. Permíteche realizar varias accións, como bloquear o dispositivo, controlar o volume, axustar o brillo e facer capturas de pantalla."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controla o dispositivo a través dun menú grande"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Configuración do menú de accesibilidade"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botóns grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumenta o tamaño dos botóns do menú de accesibilidade"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Axuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brillo: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume da música: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-gu/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-gu/strings.xml
new file mode 100644
index 0000000..adada82
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-gu/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ઍક્સેસિબિલિટી મેનૂ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ઍક્સેસિબિલિટી મેનૂ તમારા ડિવાઇસને નિયંત્રિત કરવા માટે મોટું ઑન-સ્ક્રીન મેનૂ પૂરું પાડે છે. તમે તમારા ડિવાઇસને લૉક કરી શકો છો, વૉલ્યૂમ અને બ્રાઇટનેસ નિયંત્રિત કરી શકો છો, સ્ક્રીનશૉટ લઈ શકો છો અને બીજું ઘણું બધું કરી શકો છો."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ઍક્સેસિબિલિટી સેટિંગ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"વૉલ્યૂમ"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"વૉલ્યૂમ નિયંત્રણો"</string>
+ <string name="power_label" msgid="7699720321491287839">"પાવર"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"પાવર વિકલ્પો"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"તાજેતરની ઍપ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"લૉક સ્ક્રીન"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ઝડપી સેટિંગ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"નોટિફિકેશન"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"સ્ક્રીનશૉટ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"સ્ક્રીનશૉટ લો"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"વૉલ્યૂમ વધારો"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"વૉલ્યૂમ ઘટાડો"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"બ્રાઇટનેસ વધારો"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"બ્રાઇટનેસ ઘટાડો"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"પાછલી સ્ક્રીન પર જાઓ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"આગલી સ્ક્રીન પર જાઓ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ઍક્સેસિબિલિટી મેનૂ તમારા ડિવાઇસને નિયંત્રિત કરવા માટે મોટું ઑન-સ્ક્રીન મેનૂ પૂરું પાડે છે. તમે તમારા ડિવાઇસને લૉક કરી શકો છો, વૉલ્યૂમ અને બ્રાઇટનેસ નિયંત્રિત કરી શકો છો, સ્ક્રીનશૉટ લઈ શકો છો અને બીજું ઘણું બધું કરી શકો છો."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"મોટા મેનૂ મારફતે ડિવાઇસને નિયંત્રિત કરો"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ઍક્સેસિબિલિટી મેનૂ સેટિંગ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"મોટા બટન"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ઍક્સેસિબિલિટી મેનૂ બટનનું કદ વધારો"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"સહાય"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"બ્રાઇટનેસ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"મ્યુઝિકનું વૉલ્યૂમ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
new file mode 100644
index 0000000..ee55895
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"सुलभता मेन्यू"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"सुलभता मेन्यू, स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इसकी मदद से, अपने डिवाइस को कंट्रोल किया जा सकता है. इस मेन्यू में जाकर, अपना डिवाइस लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ कंट्रोल करने जैसे कई दूसरे काम किए जा सकते हैं."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"सुलभता सेटिंग"</string>
+ <string name="volume_label" msgid="3682221827627150574">"आवाज़"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"आवाज़ कम या ज़्यादा करने का बटन"</string>
+ <string name="power_label" msgid="7699720321491287839">"पावर बटन"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"पावर बटन के विकल्प"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"हाल में इस्तेमाल किए गए ऐप्लिकेशन"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"लॉक स्क्रीन"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"क्विक सेटिंग"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"सूचनाएं"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"स्क्रीनशॉट"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"स्क्रीनशॉट लें"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"आवाज़ बढ़ाएं"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"आवाज़ कम करें"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"स्क्रीन की रोशनी बढ़ाएं"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"स्क्रीन की रोशनी कम करें"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"पिछली स्क्रीन पर जाएं"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"अगली स्क्रीन पर जाएं"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"सुलभता मेन्यू, स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इसकी मदद से, अपने डिवाइस को कंट्रोल किया जा सकता है. इस मेन्यू में जाकर, अपना डिवाइस लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ कंट्रोल करने जैसे कई दूसरे काम किए जा सकते हैं."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"बड़े मेन्यू की मदद से डिवाइस को कंट्रोल करें"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू सेटिंग"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"बड़े बटन"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"सुलभता मेन्यू के बटनाें का आकार बढ़ाएं"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"सहायता"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"स्क्रीन की रोशनी <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"संगीत की आवाज़ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
new file mode 100644
index 0000000..0be6f75
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Izbornik pristupačnosti"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Izbornik pristupačnosti pruža velik izbornik na zaslonu u svrhu upravljanja uređajem. Možete zaključati uređaj, upravljati glasnoćom i svjetlinom, izrađivati snimke zaslona i drugo."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Asistent"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Postavke pristupačnosti"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Glasnoća"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrole za glasnoću"</string>
+ <string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaključan zaslon"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Brze postavke"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Obavijesti"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Snimka zaslona"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Snimi zaslon"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Pojačaj"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Stišaj"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Pojačaj svjetlinu"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Smanji svjetlinu"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Idi na prethodni zaslon"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Idi na sljedeći zaslon"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Izbornik pristupačnosti pruža velik izbornik na zaslonu u svrhu upravljanja uređajem. Možete zaključati uređaj, upravljati glasnoćom i svjetlinom, izrađivati snimke zaslona i drugo."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Upravljanje uređajem pomoću velikog izbornika"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke izbornika pristupačnosti"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veliki gumbi"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećanje veličine gumba izbornika Pristupačnosti"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomoć"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Svjetlina <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Glasnoća glazbe <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hu/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hu/strings.xml
new file mode 100644
index 0000000..9dce8ae
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hu/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Kisegítő lehetőségek menüje"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"A Kisegítő lehetőségek menüje az eszköz vezérlésére szolgáló nagyméretű, képernyőn megjelenő menü. Lezárhatja vele az eszközt, szabályozhatja a hang- és a fényerőt, képernyőképeket készíthet, és egyebekre is használhatja."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Segéd"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Kisegítő lehetőségek beállításai"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Hangerő"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Hangerő-szabályozó"</string>
+ <string name="power_label" msgid="7699720321491287839">"Bekapcsológomb"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Bekapcsológomb beállításai"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Legutóbbi alkalmazások"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lezárási képernyő"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Gyorsbeállítások"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Értesítések"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Képernyőkép"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Képernyőkép készítése"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Hangerő növelése"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Hangerő csökkentése"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Fényerő növelése"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Fényerő csökkentése"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ugrás az előző képernyőre"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ugrás a következő képernyőre"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"A Kisegítő lehetőségek menüje az eszköz vezérlésére szolgáló nagyméretű, képernyőn megjelenő menü. Lezárhatja az eszközt, szabályozhatja a hang- és a fényerőt, képernyőképeket készíthet, és egyebekre is használhatja a funkciót."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Nagyméretű menün keresztül vezérelheti eszközét"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"A kisegítő lehetőségek menü beállításai"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Nagy gombok"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"A Kisegítő lehetőségek menüben található gombok méretének növelése"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Súgó"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Fényerő: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Zene hangereje: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hy/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hy/strings.xml
new file mode 100644
index 0000000..52d5d0e3
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hy/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Հատուկ գործառույթների ընտրացանկ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Հատուկ գործառույթների մեծ ընտրացանկը նախատեսված է ձեր սարքը կառավարելու համար։ Դուք կարող եք կողպել ձեր հեռախոսը, կարգավորել պայծառությունը և ձայնի ուժգնությունը, սքրինշոթներ անել և այլն։"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Օգնական"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Հատուկ գործառույթների կարգավորումներ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Ձայն"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Ձայնի ուժգնության կառավարներ"</string>
+ <string name="power_label" msgid="7699720321491287839">"Սնուցման կոճակ"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Սնուցման կոճակի ընտրանքներ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Վերջին օգտագործած հավելվածները"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Կողպէկրան"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Արագ կարգավորումներ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Ծանուցումներ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Սքրինշոթ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ստանալ սքրինշոթը"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Բարձրացնել ձայնը"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Իջեցնել ձայնը"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Ավելացնել պայծառությունը"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Պակասեցնել պայծառությունը"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Անցնել նախորդ էկրան"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Անցնել հաջորդ էկրան"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Հատուկ գործառույթների մեծ ընտրացանկը նախատեսված է ձեր սարքը կառավարելու համար: Դուք կարող եք կողպել ձեր հեռախոսը, կարգավորել պայծառությունը և ձայնի ուժգնությունը, սքրինշոթներ անել և այլն։"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Կառավարել սարքը մեծ ընտրացանկի միջոցով"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Հատուկ գործառույթների ընտրացանկի կարգավորումներ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Մեծ կոճակներ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Մեծացնել «Հատուկ գործառույթների» ընտրացանկի կոճակները"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Օգնություն"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Պայծառությունը՝ <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Երաժշտության ձայնի ուժգնությունը՝ <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-in/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-in/strings.xml
new file mode 100644
index 0000000..d58cf89
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-in/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Aksesibilitas"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu Aksesibilitas menyediakan menu di layar dengan ukuran besar untuk mengontrol perangkat Anda. Anda dapat mengunci perangkat, mengontrol volume dan kecerahan, mengambil screenshot, dan banyak lagi."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asisten"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Setelan Aksesibilitas"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrol volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opsi power"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplikasi terbaru"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Layar kunci"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Setelan Cepat"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifikasi"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ambil screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Naikkan volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Turunkan volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Tingkatkan kecerahan"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Kurangi kecerahan"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Buka layar sebelumnya"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Buka layar berikutnya"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menu Aksesibilitas menyediakan menu di layar dengan ukuran besar untuk mengontrol perangkat Anda. Anda dapat mengunci perangkat, mengontrol volume dan kecerahan, mengambil screenshot, dan banyak lagi."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrol perangkat melalui menu berukuran besar"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Setelan Menu Aksesibilitas"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Tombol besar"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Perbesar ukuran Tombol Menu Aksesibilitas"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Bantuan"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Kecerahan <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume musik <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-is/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-is/strings.xml
new file mode 100644
index 0000000..2a803c1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-is/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Aðgengisvalmynd"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Aðgengisvalmyndin er stór valmynd sem birtist á skjánum sem má nota til að stjórna tækinu. Þú getur læst tækinu, stjórnað hljóðstyrk og birtustigi, tekið skjámyndir og fleira."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Hjálpari"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Aðgengisstillingar"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Hljóðstyrkur"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Stýringar hljóðstyrks"</string>
+ <string name="power_label" msgid="7699720321491287839">"Orka"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Orkuvalkostir"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nýleg forrit"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lásskjár"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Flýtistillingar"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Tilkynningar"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skjámynd"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Taka skjámynd"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Hækka hljóð"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Lækka hljóð"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Auka birtustig"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Minnka birtustig"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Fara á fyrri skjá"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Fara á næsta skjá"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Aðgengisvalmyndin er stór valmynd sem birtist á skjánum sem má nota til að stjórna tækinu. Þú getur læst tækinu, stjórnað hljóðstyrk og birtustigi, tekið skjámyndir og fleira."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Stjórna tæki í gegnum stóra valmynd"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Aðgengisvalmyndarstillingar"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Stórir hnappar"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Stækka hnappa aðgengisvalmyndar"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hjálp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Birtustig <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Hljóðstyrkur tónlistar <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-it/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-it/strings.xml
new file mode 100644
index 0000000..cef3677
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-it/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Accessibilità"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Il Menu Accessibilità mostra sullo schermo un menu di grandi dimensioni per permetterti di controllare il dispositivo. Puoi bloccare il dispositivo, regolare il volume e la luminosità, acquisire screenshot e altro ancora."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistente"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistente"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Impostazioni di accessibilità"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controlli del volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Accensione"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opzioni di accensione"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"App recenti"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Schermata di blocco"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Impostazioni rapide"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notifiche"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Acquisisci screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Alza il volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Abbassa il volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumenta luminosità"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Diminuisci luminosità"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Vai alla schermata precedente"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Vai alla schermata successiva"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Il Menu Accessibilità mostra sullo schermo un menu di grandi dimensioni per permetterti di controllare il dispositivo. Puoi bloccare il dispositivo, regolare il volume e la luminosità, acquisire screenshot e altro ancora."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlla il dispositivo tramite un menu di grandi dimensioni"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Impostazioni del menu Accessibilità"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Pulsanti grandi"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumenta le dimensioni dei pulsanti del menu Accessibilità"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Guida"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Luminosità: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume musica: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml
new file mode 100644
index 0000000..6335e96
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"תפריט נגישות"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"תפריט הנגישות הוא תפריט גדול שמופיע במסך ומאפשר לשלוט במכשיר. אפשר לנעול את המכשיר, לשלוט בעוצמת הקול ובבהירות, לצלם צילומי מסך ועוד."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"הגדרות נגישות"</string>
+ <string name="volume_label" msgid="3682221827627150574">"עוצמת הקול"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"שליטה בעוצמת הקול"</string>
+ <string name="power_label" msgid="7699720321491287839">"הפעלה"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"אפשרויות הפעלה"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"אפליקציות אחרונות"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"מסך נעילה"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"הגדרות מהירות"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"התראות"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"צילום מסך"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"שמירת צילום של המסך"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"הגברת עוצמת הקול"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"החלשת עוצמת הקול"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"הגברת הבהירות"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"הפחתת הבהירות"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"מעבר למסך הקודם"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"מעבר למסך הבא"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"תפריט הנגישות הוא תפריט גדול שמופיע במסך ומאפשר לשלוט במכשיר. אפשר לנעול את המכשיר, לשלוט בעוצמת הקול ובבהירות, לצלם צילומי מסך ועוד."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"שליטה במכשיר באמצעות התפריט הגדול"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"הגדרות של תפריט נגישות"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"לחצנים גדולים"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"הגדלת הלחצנים של תפריט הנגישות"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"עזרה"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"בהירות %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"עוצמת הקול של המוזיקה %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ja/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ja/strings.xml
new file mode 100644
index 0000000..d5ef005
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ja/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ユーザー補助機能メニュー"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ユーザー補助メニューは、デバイスを操作するための画面上の大きなメニューです。デバイスのロック、音量や明るさの調節、スクリーンショットの撮影などを行えます。"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"アシスタント"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"アシスタント"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ユーザー補助機能の設定"</string>
+ <string name="volume_label" msgid="3682221827627150574">"音量"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"音量を調節"</string>
+ <string name="power_label" msgid="7699720321491287839">"電源"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"電源オプション"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"最近使ったアプリ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ロック画面"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"クイック設定"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"通知"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"スクリーンショット"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"スクリーンショットを撮る"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"音量を上げる"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"音量を下げる"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"明るさを上げる"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"明るさを下げる"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"前の画面に移動"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"次の画面に移動"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ユーザー補助メニューは、デバイスを操作するための画面上の大きなメニューです。デバイスのロック、音量や明るさの調節、スクリーンショットの撮影などを行えます。"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"大きなメニューでデバイスを操作します"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ユーザー補助機能メニューの設定"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"大きいボタン"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ユーザー補助機能メニューのボタンを大きくする"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ヘルプ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"明るさ <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"音楽の音量 <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ka/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ka/strings.xml
new file mode 100644
index 0000000..3ba5adc
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ka/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"მარტივი წვდომის მენიუ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"მარტივი წვდომის მენიუ გთავაზობთ ვრცელ, ეკრანულ მენიუს მოწყობილობის სამართავად. თქვენ შეგიძლიათ, ჩაკეტოთ მოწყობილობა, მართოთ ხმის სიმძლავრე და სიკაშკაშე, გადაიღოთ ეკრანის ანაბეჭდები და ა.შ."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"ასისტენტი"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"ასისტენტი"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"მარტივი წვდომის პარამეტრები"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ხმა"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ხმის მართვის საშუალებები"</string>
+ <string name="power_label" msgid="7699720321491287839">"ელკვება"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ელკვების ვარიანტები"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ბოლოდროინდელი აპები"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ჩაკეტილი ეკრანი"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"სწრაფი პარამეტრები"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"შეტყობინებები"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ეკრანის ანაბეჭდი"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ეკრანის ანაბეჭდის გადაღება"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ხმის აწევა"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ხმის დაწევა"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"სიკაშკაშის მომატება"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"სიკაშკაშის დაკლება"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"წინა ეკრანზე გადასვლა"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"შემდეგ ეკრანზე გადასვლა"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"მარტივი წვდომის მენიუ გთავაზობთ ვრცელ, ეკრანულ მენიუს მოწყობილობის სამართავად. თქვენ შეგიძლიათ, ჩაკეტოთ მოწყობილობა, მართოთ ხმის სიმძლავრე და სიკაშკაშე, გადაიღოთ ეკრანის ანაბეჭდები და ა.შ."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"მართეთ მოწყობილობა დიდი მენიუს მეშვეობით"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"მარტივი წვდომის მენიუს პარამეტრები"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"დიდი ღილაკები"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"მარტივი წვდომის მენიუს ღილაკების ზომის გაზრდა"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"დახმარება"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"სიკაშკაშე: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"მუსიკის ხმა: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-kk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kk/strings.xml
new file mode 100644
index 0000000..b7fbaa8
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kk/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Арнайы мүмкіндіктер мәзірі"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Арнайы мүмкіндіктер мәзірінде құрылғыны басқаруға арналған үлкейтілген экран мәзірі бар. Ол арқылы құрылғыны құлыптай, дыбыс деңгейі мен түс ашықтығын басқара, скриншот түсіре және т.б. әрекеттерді орындай аласыз."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Арнайы мүмкіндіктер параметрлері"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Дыбыс деңгейі"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Дыбыс деңгейін басқару элементтері"</string>
+ <string name="power_label" msgid="7699720321491287839">"Қуат түймесі"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Қуат түймесінің опциялары"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Соңғы пайдаланылған қолданбалар"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Құлып экраны"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Жылдам параметрлер"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Хабарландырулар"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Скриншот"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Скриншот жасау"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Дыбысын арттыру"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Дыбысын азайту"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Жарықтығын арттыру"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Жарықтығын азайту"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Алдыңғы экранға өту"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Келесі экранға өту"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Арнайы мүмкіндіктер мәзірінде құрылғыны басқаруға арналған үлкейтілген экран мәзірі бар. Ол арқылы құрылғыны құлыптай, дыбыс деңгейі мен түс ашықтығын басқара, скриншот түсіре және т. б. әрекеттерді орындай аласыз."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Құрылғыны үлкейтілген экран мәзірі арқылы басқару"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Арнайы мүмкіндіктер мәзірі параметрлері"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Үлкен түймелер"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"\"Арнайы мүмкіндіктер\" мәзірі түймелерін үлкейту"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Анықтама"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Жарықтығы: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Музыканың дыбыс қаттылығы: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml
new file mode 100644
index 0000000..6bd1274
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-km/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ម៉ឺនុយភាពងាយស្រួល"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ម៉ឺនុយភាពងាយស្រួលផ្ដល់ម៉ឺនុយធំនៅលើអេក្រង់ ដើម្បីគ្រប់គ្រងឧបករណ៍របស់អ្នក។ អ្នកអាចចាក់សោឧបករណ៍របស់អ្នក គ្រប់គ្រងកម្រិតសំឡេងនិងពន្លឺ ថតរូបអេក្រង់ និងអ្វីៗច្រើនទៀត។"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"ជំនួយការ"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ការកំណត់ភាពងាយស្រួល"</string>
+ <string name="volume_label" msgid="3682221827627150574">"កម្រិតសំឡេង"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ការគ្រប់គ្រងកម្រិតសំឡេង"</string>
+ <string name="power_label" msgid="7699720321491287839">"ថាមពល"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ជម្រើសថាមពល"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"កម្មវិធីថ្មីៗ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"អេក្រង់ចាក់សោ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ការកំណត់រហ័ស"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ការជូនដំណឹង"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"រូបថតអេក្រង់"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ថតរូបថតអេក្រង់"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ដំឡើងកម្រិតសំឡេង"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"បន្ថយកម្រិតសំឡេង"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"បង្កើនពន្លឺ"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"បន្ថយពន្លឺ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ចូលទៅកាន់អេក្រង់មុន"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ចូលទៅកាន់អេក្រង់បន្ទាប់"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ម៉ឺនុយភាពងាយស្រួលផ្ដល់ម៉ឺនុយធំនៅលើអេក្រង់ ដើម្បីគ្រប់គ្រងឧបករណ៍របស់អ្នក។ អ្នកអាចចាក់សោឧបករណ៍របស់អ្នក គ្រប់គ្រងកម្រិតសំឡេងនិងពន្លឺ ថតរូបអេក្រង់ និងអ្វីៗច្រើនទៀត។"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"គ្រប់គ្រងឧបករណ៍តាមរយៈម៉ឺនុយធំ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ការកំណត់ម៉ឺនុយភាពងាយស្រួល"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ប៊ូតុងធំ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"បង្កើនទំហំប៊ូតុងម៉ឺនុយភាពងាយស្រួល"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ជំនួយ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ពន្លឺ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"កម្រិតសំឡេងតន្ត្រី <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml
new file mode 100644
index 0000000..627cfc1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-kn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ನಿಯಂತ್ರಿಸುವುದಕ್ಕಾಗಿ ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು ದೊಡ್ಡ ಸ್ಕ್ರೀನ್ ಮೆನುವನ್ನು ಒದಗಿಸುತ್ತದೆ. ನೀವು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡಬಹುದು, ವಾಲ್ಯೂಮ್ ಮತ್ತು ಪ್ರಖರತೆಯನ್ನು ನಿಯಂತ್ರಿಸಬಹುದು, ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು ಮತ್ತು ಇನ್ನೂ ಹೆಚ್ಚಿನವನ್ನು ಮಾಡಬಹುದು."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ಪ್ರವೇಶಿಸುವಿಕೆ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ಧ್ವನಿಯ ಶಕ್ತಿ"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ಧ್ವನಿಯ ಶಕ್ತಿಯ ನಿಯಂತ್ರಕಗಳು"</string>
+ <string name="power_label" msgid="7699720321491287839">"ಪವರ್ ಬಟನ್"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ಪವರ್ ಆಯ್ಕೆಗಳು"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ಲಾಕ್ ಪರದೆ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ವಾಲ್ಯೂಮ್ ಜಾಸ್ತಿ"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ವಾಲ್ಯೂಮ್ ಕಡಿಮೆ"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ಪ್ರಖರತೆ ಹೆಚ್ಚು ಮಾಡಿ"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ಪ್ರಖರತೆ ಕಡಿಮೆ ಮಾಡಿ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ಹಿಂದಿನ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಿ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ಮುಂದಿನ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಿ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಲು ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು ದೊಡ್ಡ ಸ್ಕ್ರೀನ್ ಮೆನುವನ್ನು ಒದಗಿಸುತ್ತದೆ. ನೀವು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡಬಹುದು, ವಾಲ್ಯೂಮ್ ಮತ್ತು ಪ್ರಖರತೆಯನ್ನು ನಿಯಂತ್ರಿಸಬಹುದು, ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು ಮತ್ತು ಇನ್ನೂ ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಬಹುದು."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ದೊಡ್ಡ ಮೆನುವಿನ ಮೂಲಕ ಸಾಧನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ದೊಡ್ಡ ಬಟನ್ಗಳು"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ಪ್ರವೇಶಿಸುವಿಕೆ ಮೆನು ಬಟನ್ಗಳ ಗಾತ್ರವನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ಸಹಾಯ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ಪ್ರಕಾಶಮಾನ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ಸಂಗೀತ ವಾಲ್ಯೂಮ್ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml
new file mode 100644
index 0000000..f2495f0
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"접근성 메뉴"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"접근성 메뉴를 사용하면 화면에 크게 표시되는 메뉴로 기기를 제어할 수 있습니다. 기기 잠금, 볼륨 및 밝기 조절, 스크린샷 찍기 등의 작업이 지원됩니다."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"어시스턴트"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"접근성 설정"</string>
+ <string name="volume_label" msgid="3682221827627150574">"볼륨"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"볼륨 조정"</string>
+ <string name="power_label" msgid="7699720321491287839">"전원"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"전원 옵션"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"최근 앱"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"잠금 화면"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"빠른 설정"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"알림"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"스크린샷"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"스크린샷 촬영"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"볼륨 크게"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"볼륨 작게"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"밝기 높이기"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"밝기 낮추기"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"이전 화면으로 이동"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"다음 화면으로 이동"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"접근성 메뉴를 사용하면 화면에 크게 표시되는 메뉴로 기기를 제어할 수 있습니다. 기기 잠금, 볼륨 및 밝기 조절, 스크린샷 찍기 등의 작업이 지원됩니다."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"큰 메뉴로 기기 제어"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"접근성 메뉴 설정"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"큰 버튼"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"접근성 메뉴 버튼 크기 늘리기"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"도움말"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"밝기 <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"음악 볼륨 <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml
new file mode 100644
index 0000000..c376cf4
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ky/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Атайын мүмкүнчүлүктөр менюсу"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Атайын мүмкүнчүлүктөр менюсу аркылуу түзмөгүңүздү кулпулап, үнүн катуулатып/акырындатып, экрандын жарык деңгээлин тууралап, скриншот тартып жана башка нерселерди жасай аласыз."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Жардамчы"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Атайын мүмкүнчүлүктөрдүн параметрлери"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Үндүн катуулугу"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Үндү башкаруу элементтери"</string>
+ <string name="power_label" msgid="7699720321491287839">"Кубат"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Кубат параметрлери"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Акыркы колдонмолор"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Кулпуланган экран"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Ыкчам жөндөөлөр"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Билдирмелер"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Скриншот"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Скриншот тартып алуу"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Катуулатуу"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Акырындатуу"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Жарыктыгын көбөйтүү"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Күңүртүрөөк"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Мурунку экранга өтүү"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Кийинки экранга өтүү"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Атайын мүмкүнчүлүктөр менюсу — бул түзмөгүңүздү көзөмөлдөөнү жеңилдетүүгө ылайыкташтырылган экрандагы чоң меню. Түзмөгүңүздү кулпулап, үнүнүн катуулугун жана экрандын жарыктыгын көзөмөлдөп, скриншотторду тартып жана башка аракеттерди аткара аласыз."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Түзмөктү чоң менюдан башкаруу"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Атайын мүмкүнчүлүктөр менюсунун параметрлери"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Чоң баскычтар"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Атайын мүмкүнчүлүктөр менюсундагы баскычтардын өлчөмүн чоңойтот"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Жардам"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Жарыктыгы <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Музыканын үнүнүн катуулугу <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-lo/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lo/strings.xml
new file mode 100644
index 0000000..85891a9
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lo/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ເມນູການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ເມນູການຊ່ວຍເຂົ້າເຖິງຈະສະໜອງເມນູຢູ່ໜ້າຈໍຂະໜາດໃຫຍ່ເພື່ອຄວບຄຸມອຸປະກອນຂອງທ່ານ. ທ່ານສາມາດລັອກອຸປະກອນຂອງທ່ານ, ຄວບຄຸມລະດັບສຽງ ແລະ ຄວາມສະຫວ່າງ, ຖ່າຍຮູບໜ້າຈໍ ແລະ ອື່ນໆໄດ້."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"ຜູ້ຊ່ວຍ"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ການຕັ້ງຄ່າການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ລະດັບສຽງ"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ຕົວຄວບຄຸມລະດັບສຽງ"</string>
+ <string name="power_label" msgid="7699720321491287839">"ພະລັງງານ"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ຕົວເລືອກພະລັງງານ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ແອັບຫຼ້າສຸດ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ໜ້າຈໍລັອກ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ການຕັ້ງຄ່າດ່ວນ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ການແຈ້ງເຕືອນ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ຮູບໜ້າຈໍ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ຖ່າຍຮູບໜ້າຈໍ"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ເພີ່ມສຽງຂຶ້ນ"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ຄ່ອຍສຽງລົງ"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ເພີ່ມຄວາມສະຫວ່າງຂຶ້ນ"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ຫຼຸດຄວາມສະຫວ່າງລົງ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ໄປທີ່ໜ້າຈໍກ່ອນໜ້າ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ໄປທີ່ໜ້າຈໍຖັດໄປ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ເມນູການຊ່ວຍເຂົ້າເຖິງຈະສະໜອງເມນູຢູ່ໜ້າຈໍຂະໜາດໃຫຍ່ເພື່ອຄວບຄຸມອຸປະກອນຂອງທ່ານ. ທ່ານສາມາດລັອກອຸປະກອນຂອງທ່ານ, ຄວບຄຸມລະດັບສຽງ ແລະ ຄວາມສະຫວ່າງ, ຖ່າຍຮູບໜ້າຈໍ ແລະ ອື່ນໆໄດ້."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ຄວບຄຸມອຸປະກອນຜ່ານເມນູໃຫຍ່"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ການຕັ້ງຄ່າເມນູການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ປຸ່ມໃຫຍ່"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ເພີ່ມຂະໜາດຂອງປຸ່ມເມນູການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ຊ່ວຍເຫຼືອ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ຄວາມສະຫວ່າງ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ລະດັບສຽງເພງ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-lt/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lt/strings.xml
new file mode 100644
index 0000000..b4d804c
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lt/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Pritaikymo neįgaliesiems meniu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Naudodami pritaikomumo meniu galite atidaryti didelį ekrane pateikiamą meniu, skirtą įrenginiui valdyti. Galite užrakinti įrenginį, valdyti garsumą ir šviesumą, užfiksuoti ekrano kopijas ir atlikti kitus veiksmus."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Padėjėjas"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Padėjėjas"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Pritaikymo neįgaliesiems nustatymai"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Garsumas"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Garsumo valdikliai"</string>
+ <string name="power_label" msgid="7699720321491287839">"Maitinimas"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Maitinimo parinktys"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Naujausios programos"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Užrakinimo ekranas"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Spartieji nustatymai"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Pranešimai"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Ekrano kopija"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Padaryti ekrano kopiją"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Garsumo didinimas"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Garsumo mažinimas"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Šviesumo didinimas"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Šviesumo mažinimas"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Eiti į ankstesnį ekraną"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Eiti į kitą ekraną"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Naudodami pritaikomumo meniu galite atidaryti didelį ekrane pateikiamą meniu, skirtą įrenginiui valdyti. Galite užrakinti įrenginį, valdyti garsumą ir šviesumą, užfiksuoti ekrano kopijas ir atlikti kitus veiksmus."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Valdykite įrenginį naudodami didelį meniu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Pritaikymo neįgaliesiems meniu nustatymai"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Dideli mygtukai"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Padidinti pritaikymo neįgaliesiems meniu mygtukų dydį"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pagalba"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Šviesumas: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Muzikos garsumas: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-lv/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lv/strings.xml
new file mode 100644
index 0000000..a40b525
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-lv/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Pieejamības izvēlne"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Pieejamības izvēlne ir liela ekrāna izvēlne, ar ko varat kontrolēt ierīci. Varat bloķēt ierīci, kontrolēt skaļumu un spilgtumu, veidot ekrānuzņēmumus un paveikt daudz ko citu."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistents"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Pieejamības iestatījumi"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Skaļums"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Skaļuma vadīklas"</string>
+ <string name="power_label" msgid="7699720321491287839">"Barošana"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Barošanas opcijas"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Pēdējās izmantotās lietotnes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Bloķēšanas ekrāns"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Ātrie iestatījumi"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Paziņojumi"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Ekrānuzņēmums"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Izveidot ekrānuzņēmumu"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Palielināt skaļumu"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Samazināt skaļumu"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Palielināt spilgtumu"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Samazināt spilgtumu"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Pāriet uz iepriekšējo ekrānu"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Pāriet uz nākamo ekrānu"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Pieejamības izvēlne nodrošina lielu ekrāna izvēlni, ko varat izmantot ierīces kontrolēšanai. Varat bloķēt ierīci, kontrolēt skaļumu un spilgtumu, veidot ekrānuzņēmumus un paveikt daudz ko citu."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrolējiet ierīci, izmantojot lielu izvēlni"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Pieejamības izvēlnes iestatījumi"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Lielas pogas"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Palielināt pieejamības izvēlnes pogu lielumu"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Palīdzība"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Spilgtums: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Mūzikas skaļums: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-mk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mk/strings.xml
new file mode 100644
index 0000000..4a710cc
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mk/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Мени за пристапност"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"„Менито за пристапност“ ви овозможува да го контролирате уредот преку големо мени на екранот. Може да го заклучите уредот, да ги контролирате јачината на звукот и осветленоста, да правите слики од екранот и друго."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Помошник"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Пристапност"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Јачина на звук"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Контроли за јачина на звук"</string>
+ <string name="power_label" msgid="7699720321491287839">"Напојување"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Опции за напојување"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Неодамнешни апликации"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Заклучен екран"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Брзи поставки"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Известувања"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Слика од екранот"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Направи слика од екранот"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Зголеми звук"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Намали звук"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Осветлете"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Затемнете"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Оди на претходниот екран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Оди на следниот екран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"„Менито за пристапност“ ви овозможува да го контролирате уредот преку големо мени на екранот. Може да го заклучите уредот, да ги контролирате јачината на звукот и осветленоста, да правите слики од екранот и друго."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Контролирајте го уредот преку големо мени"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Поставки за мени за прист."</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Големи копчиња"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Зголеми ги копчињата на менито за пристапност"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Помош"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Осветленост <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Јачина на звук за музика <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ml/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ml/strings.xml
new file mode 100644
index 0000000..38471e1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ml/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ഉപയോഗസഹായി മെനു"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"നിങ്ങളുടെ ഉപകരണം നിയന്ത്രിക്കുന്നതിന്, ഉപയോഗസഹായി മെനു വലിയൊരു ഓൺ-സ്ക്രീൻ മെനു നൽകുന്നു. ഉപകരണം ലോക്ക് ചെയ്യാനും ശബ്ദവും തെളിച്ചവും നിയന്ത്രിക്കാനും സ്ക്രീൻ ഷോട്ടുകൾ എടുക്കാനും മറ്റും നിങ്ങൾക്ക് കഴിയും."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"അസിസ്റ്റന്റ്"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"പ്രവേശനക്ഷമത ക്രമീകരണം"</string>
+ <string name="volume_label" msgid="3682221827627150574">"വോളിയം"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"വോളിയം നിയന്ത്രണങ്ങൾ"</string>
+ <string name="power_label" msgid="7699720321491287839">"പവർ"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"പവർ ഓപ്ഷനുകൾ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"സമീപകാല ആപ്പുകൾ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ലോക്ക് സ്ക്രീൻ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ദ്രുത ക്രമീകരണം"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"അറിയിപ്പുകൾ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"സ്ക്രീൻഷോട്ട്"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"സ്ക്രീന്ഷോട്ട് എടുക്കുക"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ശബ്ദം കൂട്ടുക"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ശബ്ദം കുറയ്ക്കുക"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"തെളിച്ചം കൂട്ടുക"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"തെളിച്ചം കുറയ്ക്കുക"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"മുമ്പത്തെ സ്ക്രീനിലേക്ക് പോവുക"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"അടുത്ത സ്ക്രീനിലേക്ക് പോവുക"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"നിങ്ങളുടെ ഉപകരണം നിയന്ത്രിക്കുന്നതിന്, ഉപയോഗസഹായി മെനു വലിയൊരു ഓൺ-സ്ക്രീൻ മെനു നൽകുന്നു. ഉപകരണം ലോക്ക് ചെയ്യാനും ശബ്ദവും തെളിച്ചവും നിയന്ത്രിക്കാനും സ്ക്രീൻ ഷോട്ടുകൾ എടുക്കാനും മറ്റും നിങ്ങൾക്ക് കഴിയും."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"വലിയ മെനുവിലൂടെ ഉപകരണം നിയന്ത്രിക്കുക"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ഉപയോഗസഹായി മെനു ക്രമീകരണം"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"വലിയ ബട്ടണുകൾ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ഉപയോഗസഹായി മെനു ബട്ടണുകളുടെ വലുപ്പം കൂട്ടുക"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"സഹായം"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"തെളിച്ചം, <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"സംഗീത ശബ്ദം, <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-mn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mn/strings.xml
new file mode 100644
index 0000000..7c54d55
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Хандалтын цэс"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Хандалтын цэс нь танд төхөөрөмжөө том дэлгэцийн цэсээр хянах боломжийг олгоно. Та төхөөрөмжөө түгжих, дууны түвшин болон гэрэлтүүлгийг хянах, дэлгэцийн агшин авах болон бусад үйлдлийг хийж болно."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Туслах"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Хүртээмжийн тохиргоо"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Түвшин"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Түвшний хяналт"</string>
+ <string name="power_label" msgid="7699720321491287839">"Асаах/унтраах"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Асаах/унтраах сонголт"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Саяхны апп"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Түгжигдсэн дэлгэц"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Шуурхай тохиргоо"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Мэдэгдэл"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Дэлгэцний зургийг дарах"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Дэлгэцний зургийг дарах"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Дууны түвшнийг нэмэх"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Дууны түвшнийг багасгах"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Гэрэлтүүлгийг нэмэх"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Гэрэлтүүлгийг бууруулах"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Өмнөх дэлгэц рүү очих"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Дараагийн дэлгэц рүү очих"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Хандалтын цэс нь танд төхөөрөмжөө том дэлгэцийн цэсээр хянах боломжийг олгоно. Та төхөөрөмжөө түгжих, дууны түвшин болон гэрэлтүүлгийг хянах, дэлгэцийн агшин авах болон бусад үйлдлийг хийж болно."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Төхөөрөмжийг том цэсээр хянана уу"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Хандалтын цэсийн тохиргоо"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Том товчлуур"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Хандалтын цэсний товчлуурын хэмжээг томруулах"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Тусламж"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Гэрэлтүүлэг <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Хөгжмийн дууны түвшин <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-mr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mr/strings.xml
new file mode 100644
index 0000000..4497e9c
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-mr/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"अॅक्सेसिबिलिटी मेनू"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"तुमचे डिव्हाइस नियंत्रित करण्यासाठी अॅक्सेसिबिलिटी मेनू मोठा स्क्रीनवरील मेनू पुरवतो. तुम्ही तुमचे डिव्हाइस लॉक करणे, व्हॉल्यूम आणि ब्राइटनेस नियंत्रित करणे, स्क्रीनशॉट घेणे आणि आणखी बरेच काही करू शकता."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"असिस्टंट"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"अॅक्सेसिबिलिटी सेटिंग्ज"</string>
+ <string name="volume_label" msgid="3682221827627150574">"व्हॉल्यूम"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"व्हॉल्यूम नियंत्रणे"</string>
+ <string name="power_label" msgid="7699720321491287839">"पॉवर"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"पॉवर पर्याय"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"अलीकडील अॅप्स"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"लॉक स्क्रीन"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"क्विक सेटिंग्ज"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"सूचना"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"स्क्रीनशॉट"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"स्क्रीनशॉट घ्या"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"व्हॉल्यूम वाढवा"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"व्हॉल्यूम कमी करा"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ब्राइटनेस वाढवा"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"कमी ब्राइटनेस"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"मागील स्क्रीनवर जा"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"पुढील स्क्रीनवर जा"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"तुमचे डिव्हाइस नियंत्रित करण्यासाठी अॅक्सेसिबिलिटी मेनू मोठा स्क्रीनवरील मेनू पुरवतो. तुम्ही तुमचे डिव्हाइस लॉक करणे, व्हॉल्यूम आणि ब्राइटनेस नियंत्रित करणे, स्क्रीनशॉट घेणे आणि आणखी बरेच काही करू शकता."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"मोठ्या मेनूद्वारे डिव्हाइस नियंत्रित करा"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"अॅक्सेसिबिलिटी मेनू सेटिंग्ज"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"मोठी बटणे"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"अॅक्सेसिबिलिटी मेनू बटणांचा आकार वाढवा"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"मदत"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ब्राइटनेस <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"गाण्याचा व्हॉल्यूम <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml
new file mode 100644
index 0000000..64a3151
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ms/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Kebolehaksesan"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu Kebolehcapaian menyediakan menu pada skrin yang besar untuk mengawal peranti anda. Anda boleh mengunci peranti anda, mengawal kelantangan dan kecerahan, mengambil tangkapan skrin dan banyak lagi."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Tetapan Kebolehaksesan"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Kelantangan"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kawalan kelantangan"</string>
+ <string name="power_label" msgid="7699720321491287839">"Kuasa"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Pilihan kuasa"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Apl terbaharu"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Kunci skrin"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Tetapan Pantas"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Pemberitahuan"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Tangkapan skrin"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ambil tangkapan skrin"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Tambah kelantangan"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Kurangkan kelantangan"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Tambahkan kecerahan"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Kurangkan kecerahan"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Pergi ke skrin sebelumnya"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Pergi ke skrin seterusnya"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menu Kebolehcapaian menyediakan menu pada skrin yang besar untuk mengawal peranti anda. Anda boleh mengunci peranti anda, mengawal kelantangan dan kecerahan, mengambil tangkapan skrin dan pelbagai lagi."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kawal peranti melalui menu besar"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Tetapan Menu Kebolehaksesan"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Butang besar"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Besarkan saiz Butang Menu Kebolehaksesan"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Bantuan"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Kecerahan <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Kelantangan muzik <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml
new file mode 100644
index 0000000..daeb106
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-my/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"အများသုံးနိုင်မှု မီနူး"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"‘အများသုံးနိုင်မှု မီနူး’ တွင် သင့်စက်ပစ္စည်းကို စီမံရန် ကြီးမားသည့်ဖန်သားပြင်မီနူး ပါဝင်သည်။ စက်ပစ္စည်းလော့ခ်ချခြင်း၊ အသံအတိုးအကျယ်နှင့် အလင်းအမှောင် ထိန်းချုပ်ခြင်း၊ ဖန်သားပြင်ဓာတ်ပုံရိုက်ခြင်း စသည်တို့ ပြုလုပ်နိုင်သည်။"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"အများသုံးစွဲနိုင်မှု ဆက်တင်များ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"အသံအတိုးအကျယ်"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"အသံအတိုးအကျယ် ခလုတ်များ"</string>
+ <string name="power_label" msgid="7699720321491287839">"ပါဝါခလုတ်"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ပါဝါ ရွေးစရာများ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"လတ်တလောသုံး အက်ပ်များ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"လော့ခ်မျက်နှာပြင်"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"အမြန် ဆက်တင်များ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"အကြောင်းကြားချက်များ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ဖန်သားပြင်ဓာတ်ပုံ ရိုက်ရန်"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"အသံချဲ့ခလုတ်"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"အသံတိုးခလုတ်"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"တောက်ပမှု တိုးမြှင့်ရန်"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"တောက်ပမှု လျှော့ချရန်"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ယခင် မျက်နှာပြင်သို့ သွားရန်"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"နောက်မျက်နှာပြင်သို့ ဆက်သွားရန်"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"‘အများသုံးနိုင်မှု မီနူး’ တွင် သင့်စက်ပစ္စည်းကို စီမံရန် ကြီးမားသည့်ဖန်သားပြင်မီနူး ပါဝင်သည်။ စက်ပစ္စည်းလော့ခ်ချခြင်း၊ အသံအတိုးအကျယ်နှင့် အလင်းအမှောင် ထိန်းချုပ်ခြင်း၊ ဖန်သားပြင်ဓာတ်ပုံရိုက်ခြင်း စသည်တို့ ပြုလုပ်နိုင်သည်။"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ကြီးမားသည့်မီးနူးဖြင့် စက်ပစ္စည်းကို စီမံနိုင်သည်"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"အများသုံးနိုင်မှု မီနူးဆက်တင်များ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ခလုတ်အကြီးများ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"\'အများသုံးနိုင်မှု မီနူး ခလုတ်များ\' ၏ အရွယ်အစားတိုးရန်"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"အကူအညီ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"တောက်ပမှု <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ဂီတသံ အတိုးအကျယ် <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
new file mode 100644
index 0000000..ab4686a
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Tilgjengelighetsmeny"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Med Tilgjengelighet-menyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Tilgjengelighetsinnstillinger"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volum"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volumkontroller"</string>
+ <string name="power_label" msgid="7699720321491287839">"Av/på"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Av/på-alternativer"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nylige apper"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Låseskjerm"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Hurtiginnstillinger"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Varsler"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skjermdump"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermdump"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volum opp"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volum ned"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Lysstyrke opp"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Lysstyrke ned"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Gå til forrige skjerm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Gå til neste skjerm"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Med Tilgjengelighet-menyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontroller enheten med en stor meny"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Innstillinger for Tilgjengelighetsmeny"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Store knapper"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Få større knapper i Tilgjengelighetsmeny"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hjelp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Lysstyrke <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musikkvolum <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
new file mode 100644
index 0000000..82b6285
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"एक्सेसिबिलिटी मेनु"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"तपाईं आफ्नो डिभाइस नियन्त्रण गर्न एक्सेसिबिलिटी मेनुमा गई ठुलो अन स्क्रिन मेनु खोल्न सक्नुहुन्छ। तपाईं आफ्नो डिभाइस लक गर्न, भोल्युम र चमक नियन्त्रण गर्न, स्क्रिनसटहरू लिन र थप कार्यहरू गर्न सक्नुहुन्छ।"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"सहायक"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"पहुँचसम्बन्धी सेटिङहरू"</string>
+ <string name="volume_label" msgid="3682221827627150574">"भोल्युम"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"भोल्युमका नियन्त्रणहरू"</string>
+ <string name="power_label" msgid="7699720321491287839">"पावर बटन"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"पावर बटनका विकल्पहरू"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"हालका एपहरू"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"लक स्क्रिन"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"द्रुत सेटिङहरू"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"सूचनाहरू"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"स्क्रिनसट"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"स्क्रिनसट लिनुहोस्"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"भोल्युम बढाउनुहोस्"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"भोल्युम कम गर्नुहोस्"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"उज्यालो बढाउनुहोस्"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"उज्यालो कम गर्नुहोस्"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"अघिल्लो स्क्रिनमा जानुहोस्"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"अर्को स्क्रिनमा जानुहोस्"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"तपाईं आफ्नो डिभाइस नियन्त्रण गर्न एक्सेसिबिलिटी मेनुमा गई ठुलो अन स्क्रिन मेनु खोल्न सक्नुहुन्छ। तपाईं आफ्नो डिभाइस लक गर्न, भोल्युम र चमक नियन्त्रण गर्न, स्क्रिनसटहरू लिन र थप कार्यहरू गर्न सक्नुहुन्छ।"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ठुलो मेनुको सहायताले डिभाइस नियन्त्रण गर्नुहोस्"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"पहुँचसम्बन्धी मेनुका सेटिङहरू"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ठूला बटनहरू"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Accessibility मेनुका बटनहरूको आकार बढाउनुहोस्"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"मद्दत"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"चमक <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"सङ्गीतको भोल्युम <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
new file mode 100644
index 0000000..1ddf6cf
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Toegankelijkheidsmenu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Het toegankelijkheidsmenu is een groot menu op het scherm waarmee je je apparaat kunt bedienen. Je kunt onder meer je apparaat vergrendelen, het volume en de helderheid beheren en screenshots maken."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Instellingen voor toegankelijkheid"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volumebediening"</string>
+ <string name="power_label" msgid="7699720321491287839">"Voeding"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Voedingsopties"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Recente apps"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Scherm vergrendelen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Snelle instellingen"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Meldingen"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Screenshot maken"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Volume omhoog"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Volume omlaag"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Helderheid verhogen"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Helderheid verlagen"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ga naar vorig scherm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ga naar volgend scherm"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Het toegankelijkheidsmenu is een groot menu op het scherm waarmee je je apparaat kunt bedienen. Je kunt onder meer je apparaat vergrendelen, het volume en de helderheid beheren en screenshots maken."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Apparaat bedienen via groot menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Instellingen toegankelijkheidsmenu"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Grote knoppen"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Knoppen in het toegankelijkheidsmenu vergroten"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hulp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Helderheid <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Muziekvolume <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-or/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-or/strings.xml
new file mode 100644
index 0000000..dd46ae4
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-or/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ଆକ୍ସେସିବିଲିଟୀ ମେନୁ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ ଆକ୍ସେସିବିଲିଟୀ ମେନୁ ଏକ ବଡ଼ ଅନ-ସ୍କ୍ରିନ ମେନୁ ପ୍ରଦାନ କରେ। ଆପଣ ଆପଣଙ୍କ ଡିଭାଇସକୁ ଲକ କରିପାରିବେ, ଭଲ୍ୟୁମ ଓ ଉଜ୍ଜ୍ୱଳତାକୁ ନିୟନ୍ତ୍ରଣ କରିପାରିବେ, ସ୍କ୍ରିନସଟ ନେଇପାରିବେ ଏବଂ ଆହୁରି ଅନେକ କିଛି କରିପାରିବେ।"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ଭଲ୍ୟୁମ୍"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ଭଲ୍ୟୁମ୍ କଣ୍ଟ୍ରୋଲ୍"</string>
+ <string name="power_label" msgid="7699720321491287839">"ପାୱର୍"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ପାୱର୍ ବିକଳ୍ପ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ବର୍ତ୍ତମାନର ଆପ୍"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ସ୍କ୍ରୀନ୍ ଲକ୍ କରନ୍ତୁ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"କ୍ୱିକ ସେଟିଂସ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ବିଜ୍ଞପ୍ତି"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ସ୍କ୍ରିନସଟ୍"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ସ୍କ୍ରୀନଶଟ୍ ନିଅନ୍ତୁ"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ଭଲ୍ୟୁମ୍ ବଢ଼ାନ୍ତୁ"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ଭଲ୍ୟୁମ୍ କମାନ୍ତୁ"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ଉଜ୍ଜ୍ୱଳତା ବଢ଼ାନ୍ତୁ"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ଉଜ୍ଜ୍ୱଳତା କମ୍ କରନ୍ତୁ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ପୂର୍ବବର୍ତ୍ତୀ ସ୍କ୍ରିନ୍କୁ ଯାଆନ୍ତୁ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ପରବର୍ତ୍ତୀ ସ୍କ୍ରିନ୍କୁ ଯାଆନ୍ତୁ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ ଆକ୍ସେସିବିଲିଟୀ ମେନୁ ଏକ ବଡ଼ ଅନ-ସ୍କ୍ରିନ ମେନୁ ପ୍ରଦାନ କରେ। ଆପଣ ଆପଣଙ୍କ ଡିଭାଇସକୁ ଲକ କରିପାରିବେ, ଭଲ୍ୟୁମ ଓ ଉଜ୍ଜ୍ୱଳତାକୁ ନିୟନ୍ତ୍ରଣ କରିପାରିବେ, ସ୍କ୍ରିନସଟ ନେଇପାରିବେ ଏବଂ ଆହୁରି ଅନେକ କିଛି କରିପାରିବେ।"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ବଡ଼ ମେନୁ ମାଧ୍ୟମରେ ଡିଭାଇସକୁ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ଆକ୍ସେସିବିଲିଟୀ ମେନୁ ସେଟିଂସ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ବଡ଼ ବଟନ୍"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ଆକ୍ସେସିବିଲିଟୀ ମେନୁ ବଟନ୍ର ଆକାର ବଢ଼ାନ୍ତୁ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ସାହାଯ୍ୟ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ଉଜ୍ଜ୍ୱଳତା <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ସଙ୍ଗୀତର ଭଲ୍ୟୁମ୍ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pa/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pa/strings.xml
new file mode 100644
index 0000000..4ff57c0
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pa/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ ਇੱਕ ਵੱਡਾ ਆਨ-ਸਕ੍ਰੀਨ ਮੀਨੂ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਲਾਕ ਕਰ ਸਕਦੇ ਹੋ, ਅਵਾਜ਼ ਅਤੇ ਚਮਕ ਨੂੰ ਕੰਟਰੋਲ ਕਰ ਸਕਦੇ ਹੋ, ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈ ਸਕਦੇ ਹੋ ਅਤੇ ਹੋਰ ਵੀ ਬਹੁਤ ਕੁਝ।"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ਪਹੁੰਚਯੋਗਤਾ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ਅਵਾਜ਼"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ਵੌਲਿਊਮ ਕੰਟਰੋਲ"</string>
+ <string name="power_label" msgid="7699720321491287839">"ਪਾਵਰ"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ਪਾਵਰ ਵਿਕਲਪ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ਹਾਲੀਆ ਐਪਾਂ"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"ਲਾਕ ਸਕ੍ਰੀਨ"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"ਸੂਚਨਾਵਾਂ"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਓ"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ਅਵਾਜ਼ ਵਧਾਓ"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ਅਵਾਜ਼ ਘਟਾਓ"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ਚਮਕ ਵਧਾਓ"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ਚਮਕ ਘਟਾਓ"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ਪਿਛਲੀ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਓ"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ਅਗਲੀ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਓ"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ ਇੱਕ ਵੱਡਾ ਸਕ੍ਰੀਨ-ਉੱਪਰਲਾ ਮੀਨੂ ਮੁਹੱਈਆ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਲਾਕ ਕਰ ਸਕਦੇ ਹੋ, ਅਵਾਜ਼ ਅਤੇ ਚਮਕ ਨੂੰ ਕੰਟਰੋਲ ਕਰ ਸਕਦੇ ਹੋ, ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈ ਸਕਦੇ ਹੋ ਅਤੇ ਹੋਰ ਵੀ ਬਹੁਤ ਕੁਝ।"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ਵੱਡੇ ਮੀਨੂ ਰਾਹੀਂ ਡੀਵਾਈਸ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ਵੱਡੇ ਬਟਨ"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"\'ਪਹੁੰਚਯੋਗਤਾ ਮੀਨੂ\' ਬਟਨਾਂ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ਮਦਦ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ਚਮਕ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ਸੰਗੀਤ ਦੀ ਅਵਾਜ਼ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pl/strings.xml
new file mode 100644
index 0000000..829ab47
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu ułatwień dostępu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu ułatwień dostępu to duże menu ekranowe, które umożliwia obsługę urządzenia. Możesz zablokować urządzenie, zwiększyć lub zmniejszyć głośność oraz jasność, zrobić zrzut ekranu i wykonać inne działania."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asystent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Ustawienia ułatwień dostępu"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Głośność"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Przyciski sterowania głośnością"</string>
+ <string name="power_label" msgid="7699720321491287839">"Zasilanie"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opcje przycisku zasilania"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Ostatnie aplikacje"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ekran blokady"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Szybkie ustawienia"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Powiadomienia"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Zrzut ekranu"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Zapisz zrzut ekranu"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Zwiększ głośność"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Zmniejsz głośność"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Zwiększ jasność"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Zmniejsz jasność"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Przejdź do poprzedniego ekranu"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Przejdź do następnego ekranu"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menu ułatwień dostępu to duże menu ekranowe, które umożliwia obsługę urządzenia. Możesz zablokować urządzenie, zwiększyć lub zmniejszyć głośność oraz jasność, zrobić zrzut ekranu i wykonać inne działania."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Obsługuj urządzenie za pomocą dużego menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Ustawienia menu ułatwień dostępu"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Duże przyciski"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zwiększ rozmiar przycisków w menu Ułatwienia dostępu"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomoc"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Jasność: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Głośność muzyki: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rBR/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..37f0980
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rBR/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu de acessibilidade"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"\"Acessibilidade\" é um grande menu mostrado na tela para controlar seu dispositivo. Você pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de tela e muito mais."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistente"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Google Assistente"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Configurações de acessibilidade"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controles de volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Liga/desliga"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opções do botão liga/desliga"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Apps recentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Tela de bloqueio"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Config. rápida"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificações"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de tela"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Fazer uma captura de tela"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Aumentar volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Diminuir volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar o brilho"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Diminuir o brilho"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir para tela anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir para a próxima tela"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"\"Acessibilidade\" é um grande menu mostrado na tela para controlar seu dispositivo. Você pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de tela e muito mais."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlar o dispositivo com o menu grande"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Config. do menu de acessibilidade"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botões grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumentar o tamanho dos botões do menu de acessibilidade"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ajuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brilho: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume da música: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..da61be6
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt-rPT/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Acessibilidade"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"O menu Acessibilidade disponibiliza um menu grande no ecrã para controlar o dispositivo. Pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de ecrã e muito mais."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistente"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistente"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Definições de acessibilidade"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controlos do volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Ligar/desligar"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opções para ligar/desligar"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Apps recentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ecrã de bloqueio"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Definições rápidas"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificações"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de ecrã"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Fazer captura de ecrã"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Aumentar volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Diminuir volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar brilho"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Diminuir brilho"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir para o ecrã anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir para o ecrã seguinte"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"O menu Acessibilidade disponibiliza um menu grande no ecrã para controlar o dispositivo. Pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de ecrã e muito mais."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controle o dispositivo através do menu grande"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Definições do menu Acessibilidade"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botões grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumentar o tamanho dos botões do menu de acessibilidade"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ajuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brilho: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume da música: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt/strings.xml
new file mode 100644
index 0000000..37f0980
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-pt/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu de acessibilidade"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"\"Acessibilidade\" é um grande menu mostrado na tela para controlar seu dispositivo. Você pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de tela e muito mais."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistente"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Google Assistente"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Configurações de acessibilidade"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Controles de volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Liga/desliga"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opções do botão liga/desliga"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Apps recentes"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Tela de bloqueio"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Config. rápida"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificações"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captura de tela"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Fazer uma captura de tela"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Aumentar volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Diminuir volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Aumentar o brilho"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Diminuir o brilho"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Ir para tela anterior"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Ir para a próxima tela"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"\"Acessibilidade\" é um grande menu mostrado na tela para controlar seu dispositivo. Você pode bloquear o dispositivo, controlar o volume e o brilho, fazer capturas de tela e muito mais."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlar o dispositivo com o menu grande"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Config. do menu de acessibilidade"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Botões grandes"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Aumentar o tamanho dos botões do menu de acessibilidade"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ajuda"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Brilho: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume da música: <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ro/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ro/strings.xml
new file mode 100644
index 0000000..77b4318
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ro/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Meniul Accesibilitate"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Meniul Accesibilitate este un meniu mare afișat pe ecran, cu ajutorul căruia îți controlezi dispozitivul. Poți să blochezi dispozitivul, să ajustezi volumul și luminozitatea, să faci capturi de ecran și multe altele."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Setări de accesibilitate"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volum"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Comenzi pentru volum"</string>
+ <string name="power_label" msgid="7699720321491287839">"Alimentare"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opțiuni pentru alimentare"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplicații recente"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ecran de blocare"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Setări rapide"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Notificări"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Captură de ecran"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Realizează o captură de ecran"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Mărește volumul"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Redu volumul"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Mărește luminozitatea"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Redu luminozitatea"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Accesează ecranul precedent"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Accesează ecranul următor"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Meniul Accesibilitate este un meniu mare afișat pe ecran, cu ajutorul căruia îți controlezi dispozitivul. Poți să blochezi dispozitivul, să ajustezi volumul și luminozitatea, să faci capturi de ecran și multe altele."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Controlează dispozitivul cu ajutorul unui meniu mare"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Setări pentru meniul Accesibilitate"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Butoane mari"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Mărește butoanele meniului de accesibilitate"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ajutor"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Luminozitate: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volumul pentru muzică: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ru/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ru/strings.xml
new file mode 100644
index 0000000..1e9ec49
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ru/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Меню спец. возможностей"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"С помощью большого экранного меню специальных возможностей можно блокировать устройство, регулировать громкость звука и яркость экрана, делать скриншоты и выполнять другие действия."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Ассистент"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Настройки специальных возможностей"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Громкость"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Кнопки регулировки громкости"</string>
+ <string name="power_label" msgid="7699720321491287839">"Кнопка питания"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Настройки кнопки питания"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Недавние приложения"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Блокировка экрана"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Быстрые настройки"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Уведомления"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Скриншот"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Сделать скриншот"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Увеличить громкость"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Уменьшить громкость"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Увеличить яркость"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Уменьшить яркость"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Вернуться на предыдущий экран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Перейти на следующий экран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"С помощью большого экранного меню специальных возможностей можно блокировать устройство, регулировать громкость звука и яркость экрана, делать скриншоты и выполнять другие действия."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Управление устройством с помощью большого меню"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Настройки меню специальных возможностей"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Увеличить кнопки"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Увеличить размер кнопок в меню специальных возможностей"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Справка"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Яркость <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Громкость музыки <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-si/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-si/strings.xml
new file mode 100644
index 0000000..ecd4c16
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-si/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ප්රවේශ්යතා මෙනුව"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"ප්රවේශ්යතා මෙනුව ඔබගේ උපාංගය පාලනය කිරීම සඳහා විශාල තිරය මත මෙනුවක් සපයයි. ඔබට ඔබගේ උපාංගය අගුලු හැරීමට, හඬ පරිමාව සහ දීප්තිය පාලනය කිරීමට, තිර රූ ගැනීමට සහ තවත් දේ කිරීමට හැකිය."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"සහායක"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ප්රවේශ්යතා සැකසීම්"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ශබ්දය"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"හඬ පරිමා පාලන"</string>
+ <string name="power_label" msgid="7699720321491287839">"බලය"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"බලය විකල්ප"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"මෑත යෙදුම්"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"අගුලු තිරය"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"ක්ෂණික සැකසීම්"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"දැනුම්දීම්"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"තිර රුව"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"තිර රුව ගන්න"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"හඬ පරිමාව වැඩි කිරීම"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"හඬ පරිමාව අඩු කිරීම"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"දීප්තිය වැඩි කිරීම"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"දීප්තිය අඩු කිරීම"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"පෙර තිරයට යන්න"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"මීළඟ තිරයට යන්න"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"ප්රවේශ්යතා මෙනුව ඔබගේ උපාංගය පාලනය කිරීම සඳහා විශාල තිරය මත මෙනුවක් සපයයි. ඔබට ඔබගේ උපාංගය අගුලු හැරීමට, හඬ පරිමාව සහ දීප්තිය පාලනය කිරීමට, තිර රූ ගැනීමට සහ තවත් දේ කිරීමට හැකිය."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"විශාල මෙනුව හරහා උපාංගය පාලනය කරන්න"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ප්රවේශ්යතා මෙනු සැකසීම්"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"විශාල බොත්තම්"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ප්රවේශ්යතා මෙනු බොත්තම්වල ප්රමාණය වැඩි කරන්න"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"උදවු"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"දීප්තිය <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"සංගීත හඬ පරිමාව <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
new file mode 100644
index 0000000..a8c8a89
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Ponuka dostupnosti"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Nastavenia dostupnosti"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Hlasitosť"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Ovládanie hlasitosti"</string>
+ <string name="power_label" msgid="7699720321491287839">"Vypínač"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Možnosti vypínača"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nedávne aplikácie"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Uzamknutá obrazovka"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Rýchle nastavenia"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Upozornenia"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Snímka obrazovky"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Vytvoriť snímku obrazovky"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Zvýšiť hlasitosť"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Znížiť hlasitosť"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Zvýšiť jas"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Znížiť jas"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Prejsť na predchádzajúcu obrazovku"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Prejsť na ďalšiu obrazovku"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládajte zariadenie pomocou veľkej ponuky"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky Dostupnosť"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veľké tlačidlá"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky Dostupnosť"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomocník"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Jas: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Hlasitosť hudby: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sl/strings.xml
new file mode 100644
index 0000000..aaa576d
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Meni s funkcijami za ljudi s posebnimi potrebami"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Meni s funkcijami za ljudi s posebnimi potrebami je velik zaslonski meni za upravljanje naprave. V njem lahko zaklenete napravo, nastavljate glasnost in svetlost, zajamete posnetke zaslona in drugo."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Pomočnik"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Nastavitve funkcij za ljudi s posebnimi potrebami"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Glasnost"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrolniki za glasnost"</string>
+ <string name="power_label" msgid="7699720321491287839">"Vklop"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Možnosti gumba za vklop"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Zaklepanje zaslona"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Hitre nastavitve"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Obvestila"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Posnetek zaslona"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ustvarjanje posnetka zaslona"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Povečanje glasnosti"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Zmanjšanje glasnosti"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Povečanje svetlosti"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Zmanjšanje svetlosti"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Na prejšnji zaslon"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Na naslednji zaslon"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Meni s funkcijami za ljudi s posebnimi potrebami je velik zaslonski meni za upravljanje naprave. V njem lahko zaklenete napravo, nastavljate glasnost in svetlost, zajamete posnetke zaslona in drugo."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Upravljanje naprave prek velikega menija"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavitve menija s funkcijami za ljudi s posebnimi potrebami"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veliki gumbi"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povečanje velikosti gumbov menija s funkcijami za ljudi s posebnimi potrebami"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Pomoč"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Svetlost <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Glasnost glasbe <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sq/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sq/strings.xml
new file mode 100644
index 0000000..2dfe2e7
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sq/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menyja e qasshmërisë"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"\"Menyja e qasshmërisë\" ofron një meny të madhe në ekran për të kontrolluar pajisjen tënde. Mund të kyçësh pajisjen, të kontrollosh volumin dhe ndriçimin, të nxjerrësh pamje ekrani dhe të tjera."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistenti"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Cilësimet e qasshmërisë"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volumi"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Kontrollet e volumit"</string>
+ <string name="power_label" msgid="7699720321491287839">"Energjia"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Opsionet e energjisë"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Aplikacionet e fundit"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ekrani i kyçjes"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Cilësimet e shpejta"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Njoftimet"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Pamja e ekranit"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Të nxjerrë një pamje të ekranit"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Rrit volumin"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Ul volumin"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Rrit ndriçimin"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Ul ndriçimin"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Shko tek ekrani i mëparshëm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Shko tek ekrani tjetër"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"\"Menyja e qasshmërisë\" ofron një meny të madhe në ekran për të kontrolluar pajisjen tënde. Mund të kyçësh pajisjen, të kontrollosh volumin dhe ndriçimin, të nxjerrësh pamje ekrani dhe të tjera."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrollo pajisjen nëpërmjet menysë së madhe"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Cilësimet e menysë së qasshmërisë"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Butona të mëdhenj"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Rrit madhësinë e butonave të \"Menysë së qasshmërisë\""</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Ndihma"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Ndriçimi <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volumi i muzikës <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sr/strings.xml
new file mode 100644
index 0000000..6538c43
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sr/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Мени Приступачност"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Мени Приступачност пружа велики мени на екрану за контролу уређаја. Можете да закључате уређај, контролишете јачину звука и осветљеност, правите снимке екрана и друго."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Помоћник"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Подешавања приступачности"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Јачина звука"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Контроле јачине звука"</string>
+ <string name="power_label" msgid="7699720321491287839">"Напајање"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Опције напајања"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Недавне апликације"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Закључан екран"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Брза подешавања"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Обавештења"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Снимак екрана"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Сними екран"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Појачај звук"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Утишај звук"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Повећајте осветљеност"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Смањите осветљеност"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Иди на претходни екран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Иди на следећи екран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Мени Приступачност пружа велики мени на екрану за контролу уређаја. Можете да закључате уређај, контролишете јачину звука и осветљеност, правите снимке екрана и друго."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Контролишите уређај помоћу великог менија"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Подешавања менија Приступачност"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Велика дугмад"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Повећајте величину дугмади у менију за приступачност"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Помоћ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Осветљеност: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Јачина звука музике: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml
new file mode 100644
index 0000000..2e7a496
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Tillgänglighetsmenyn"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Tillgänglighetsmenyn är en stor meny på skärmen som du kan styra enheten med. Du kan låsa enheten, ställa in volym och ljusstyrka, ta skärmbilder och annat."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Tillgänglighetsinställningar"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volym"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Volymkontroller"</string>
+ <string name="power_label" msgid="7699720321491287839">"Styrka"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Strömalternativ"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Senaste apparna"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Låsskärm"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Snabbinställningar"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Aviseringar"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skärmbild"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skärmbild"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Höj volymen"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Sänk volymen"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Öka ljusstyrkan"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Minska ljusstyrkan"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Tillbaka till föregående skärm"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Fortsätt till nästa skärm"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Tillgänglighetsmenyn är en stor meny på skärmen som du kan styra enheten med. Du kan låsa enheten, ställa in volym och ljusstyrka, ta skärmbilder och annat."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Styra enheten via en stor meny"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Inställningar för tillgänglighetsmenyn"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Stora knappar"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Öka knapparnas storlek i tillgänglighetsmenyn"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Hjälp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Ljusstyrka <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musikvolym <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sw/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sw/strings.xml
new file mode 100644
index 0000000..c7a52ae
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sw/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menyu ya Ufikivu"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menyu ya Ufikivu huonyesha menyu pana iliyo kwenye skrini ili udhibiti kifaa chako. Unaweza kufunga kifaa chako, kudhibiti sauti na ung\'avu, kupiga picha ya skrini na zaidi."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Mratibu"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Mipangilio ya Ufikivu"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Sauti"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Vidhibiti vya sauti"</string>
+ <string name="power_label" msgid="7699720321491287839">"Nishati"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Chaguo za kuwasha"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Programu za hivi karibuni"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Skrini iliyofungwa"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Mipangilio ya Haraka"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Arifa"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Picha ya skrini"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Piga picha ya skrini"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Ongeza sauti"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Punguza sauti"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Ongeza ung\'aavu"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Punguza ung`aavu"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Nenda kwenye skrini iliyotangulia"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Nenda kwenye skrini inayofuata"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menyu ya Ufikivu huonyesha menyu pana iliyo kwenye skrini ili udhibiti kifaa chako. Unaweza kufunga kifaa chako, kudhibiti sauti na ung\'avu, kupiga picha ya skrini na zaidi."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Dhibiti kifaa ukitumia menyu pana"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Mipangilio ya Zana za Ufikivu"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Vitufe vikubwa"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Ongeza ukubwa wa Vitufe vya Menyu ya Ufikivu"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Usaidizi"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Ung\'avu <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Sauti ya muziki <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ta/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ta/strings.xml
new file mode 100644
index 0000000..0172b5b
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ta/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"அணுகல்தன்மை மெனு"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"அணுகல்தன்மை மெனுவானது உங்கள் சாதனத்தைக் கட்டுப்படுத்துவதற்கு, திரையில் தோன்றும் பெரிய மெனுவை வழங்குகிறது. சாதனத்தைப் பூட்டுதல், ஒலியளவையும் ஒளிர்வையும் மாற்றுதல், ஸ்கிரீன்ஷாட்களை எடுத்தல் போன்ற பலவற்றைச் செய்யலாம்."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"அணுகல்தன்மை அமைப்புகள்"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ஒலியளவு"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"ஒலியளவுக் கட்டுப்பாடுகள்"</string>
+ <string name="power_label" msgid="7699720321491287839">"பவர் பட்டன்"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"பவர் பட்டன் விருப்பங்கள்"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"சமீபத்திய ஆப்ஸ்"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"லாக் ஸ்கிரீன்"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"விரைவு அமைப்புகள்"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"அறிவிப்புகள்"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ஸ்கிரீன்ஷாட்"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"ஸ்கிரீன் ஷாட்டை எடுக்கும் பட்டன்"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"ஒலியளவை அதிகரிப்பதற்கான பட்டன்"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ஒலியளவைக் குறைக்கும்"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ஒளிர்வை அதிகரிப்பதற்கான பட்டன்"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ஒளிர்வைக் குறைக்கும்"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"முந்தைய திரைக்குச் செல்வதற்கான பட்டன்"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"அடுத்த திரைக்குச் செல்வதற்கான பட்டன்"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"அணுகல்தன்மை மெனுவானது உங்கள் சாதனத்தைக் கட்டுப்படுத்துவதற்கு, திரையில் தோன்றும் பெரிய மெனுவை வழங்குகிறது. சாதனத்தைப் பூட்டுதல், ஒலியளவையும் ஒளிர்வையும் மாற்றுதல், ஸ்கிரீன்ஷாட்களை எடுத்தல் போன்ற பலவற்றைச் செய்யலாம்."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"பெரிய மெனுவின் மூலம் சாதனத்தைக் கட்டுப்படுத்தலாம்"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"அணுகல்தன்மை மெனு அமைப்புகள்"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"பெரிய பட்டன்கள்"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"’அணுகலம்சங்கள் மெனு பட்டன்களின்’ அளவைப் பெரிதாக்கும்"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"உதவி"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ஒளிர்வு: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"இசை ஒலியளவு: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-te/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-te/strings.xml
new file mode 100644
index 0000000..54b10f1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-te/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"యాక్సెసిబిలిటీ మెనూ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"మీ పరికరాన్ని కంట్రోల్ చేయడానికి యాక్సెసిబిలిటీ మెనూ, స్క్రీన్పై పెద్ద మెనూను అందిస్తుంది. మీరు మీ పరికరాన్ని లాక్ చేయవచ్చు, వాల్యూమ్ మరియు ప్రకాశాన్ని కంట్రోల్ చేయవచ్చు, స్క్రీన్షాట్లు తీసుకోవచ్చు, మరిన్ని చేయవచ్చు."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"యాక్సెస్ సామర్థ్య సెట్టింగ్లు"</string>
+ <string name="volume_label" msgid="3682221827627150574">"వాల్యూమ్"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"వాల్యూమ్ నియంత్రణలు"</string>
+ <string name="power_label" msgid="7699720321491287839">"పవర్"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"పవర్ ఎంపికలు"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"ఇటీవలి యాప్లు"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"లాక్ స్క్రీన్"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"క్విక్ సెట్టింగ్లు"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"నోటిఫికేషన్లు"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"స్క్రీన్షాట్"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"స్క్రీన్షాట్ని తీయండి"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"వాల్యూమ్ పెంచు"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"వాల్యూమ్ తగ్గించు"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"ప్రకాశాన్ని పెంచుతుంది"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ప్రకాశాన్ని తగ్గిస్తుంది"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"మునుపటి స్క్రీన్కు వెళ్లండి"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"తదుపరి స్క్రీన్కు వెళ్లండి"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"మీ పరికరాన్ని నియంత్రించడానికి యాక్సెసిబిలిటీ మెనూ, స్క్రీన్పై పెద్ద మెనూను అందిస్తుంది. మీరు మీ పరికరాన్ని లాక్ చేయవచ్చు, వాల్యూమ్ మరియు ప్రకాశాన్ని నియంత్రించవచ్చు, స్క్రీన్షాట్లు తీసుకోవచ్చు, మరిన్ని చేయవచ్చు."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"పెద్ద మెనూ ద్వారా పరికరాన్ని నియంత్రించండి"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"యాక్సెసిబిలిటీ మెనూ సెట్టింగ్లు"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"పెద్ద బటన్లు"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"యాక్సెసిబిలిటీ మెనూ బటన్ల సైజ్ పెంచుతుంది"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"సహాయం"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ప్రకాశం <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"సంగీతం వాల్యూమ్ <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-th/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-th/strings.xml
new file mode 100644
index 0000000..5748b5c
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-th/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"เมนูการช่วยเหลือพิเศษ"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"เมนูการช่วยเหลือพิเศษเป็นเมนูขนาดใหญ่บนหน้าจอที่มีไว้ควบคุมอุปกรณ์ คุณจะล็อกอุปกรณ์ ควบคุมระดับเสียงและความสว่าง ถ่ายภาพหน้าจอ และอื่นๆ ได้"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"การตั้งค่าการช่วยเหลือพิเศษ"</string>
+ <string name="volume_label" msgid="3682221827627150574">"ระดับเสียง"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"การควบคุมเสียง"</string>
+ <string name="power_label" msgid="7699720321491287839">"เปิด/ปิด"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"ตัวเลือกสำหรับการเปิด/ปิด"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"แอปล่าสุด"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"หน้าจอล็อก"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"การตั้งค่าด่วน"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"การแจ้งเตือน"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"ภาพหน้าจอ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"จับภาพหน้าจอ"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"เพิ่มระดับเสียง"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"ลดระดับเสียง"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"เพิ่มความสว่าง"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"ลดความสว่าง"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"ไปที่หน้าจอก่อนหน้า"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"ไปที่หน้าจอถัดไป"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"เมนูการช่วยเหลือพิเศษเป็นเมนูขนาดใหญ่บนหน้าจอที่มีไว้ควบคุมอุปกรณ์ คุณจะล็อกอุปกรณ์ ควบคุมระดับเสียงและความสว่าง ถ่ายภาพหน้าจอ และอื่นๆ ได้"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"ควบคุมอุปกรณ์ผ่านเมนูขนาดใหญ่"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"การตั้งค่าเมนูการช่วยเหลือพิเศษ"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"ปุ่มใหญ่"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"เพิ่มขนาดของปุ่มเมนูการช่วยเหลือพิเศษ"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"ความช่วยเหลือ"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"ความสว่าง <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"ระดับเสียงเพลง <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-tl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-tl/strings.xml
new file mode 100644
index 0000000..ed1269b
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-tl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu ng Accessibility"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Nagbibigay ang Menu ng Accessibility ng malaking menu sa screen para sa pagkontrol sa iyong device. Magagawa mong i-lock ang iyong device, kontrolin ang volume at liwanag, kumuha ng mga screenshot, at higit pa."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Mga Setting ng Accessibility"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Volume"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Mga kontrol ng volume"</string>
+ <string name="power_label" msgid="7699720321491287839">"Power"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Mga opsyon sa power"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Mga kamakailang app"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Lock screen"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Mga Mabilisang Setting"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Mga Notification"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Screenshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Kumuha ng screenshot"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Lakasan ang volume"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Hinaan ang volume"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Taasan ang liwanag"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Babaan ang liwanag"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Pumunta sa nakaraang screen"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Pumunta sa susunod na screen"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Nagbibigay ang Menu ng Accessibility ng malaking menu sa screen para kontrolin ang iyong device. Magagawa mong i-lock ang iyong device, kontrolin ang volume at liwanag, kumuha ng mga screenshot, at higit pa."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontrolin ang device sa pamamagitan ng malaking menu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Mga Setting ng Menu ng Accessibility"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Malalaking button"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Palakihin ang Mga Button ng Menu ng Accessibility"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Tulong"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Liwanag <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Volume ng musika <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-tr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-tr/strings.xml
new file mode 100644
index 0000000..76a6ec7
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-tr/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Erişilebilirlik Menüsü"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Erişilebilirlik menüsü, cihazınızı kontrol etmeniz için geniş bir ekran menüsü sağlar. Cihazınızı kilitleyebilir, ses düzeyini ve parlaklığı kontrol edebilir, ekran görüntüsü alabilir ve daha fazlasını yapabilirsiniz."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Asistan"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Erişebilirlik Ayarları"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Ses düzeyi"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Ses denetimleri"</string>
+ <string name="power_label" msgid="7699720321491287839">"Güç"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Güç seçenekleri"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Son uygulamalar"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Kilit ekranı"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Hızlı Ayarlar"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Bildirimler"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Ekran görüntüsü"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Ekran görüntüsü al"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Sesi aç"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Sesi kıs"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Parlaklığı artır"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Parlaklığı azalt"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Önceki ekrana git"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Sonraki ekrana git"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Erişilebilirlik menüsü, cihazınızı kontrol etmeniz için geniş bir ekran menüsü sağlar. Cihazınızı kilitleyebilir, ses düzeyini ve parlaklığı kontrol edebilir, ekran görüntüsü alabilir ve daha fazlasını yapabilirsiniz."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Cihazı geniş menüyle kontrol edin"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Erişilebilirlik Menüsü Ayarları"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Büyük düğmeler"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Erişilebilirlik Menüsündeki Düğmelerin boyutunu artır"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Yardım"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Parlaklık %%<xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Müzik ses düzeyi %%<xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml
new file mode 100644
index 0000000..970ba21
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uk/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Меню спеціальних можливостей"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"За допомогою великого екранного меню спеціальних можливостей можна заблокувати пристрій, змінювати гучність і яскравість, робити знімки екрана та багато іншого."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Асистент"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Налаштування спеціальніх можливостей"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Гучність"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Регулятори гучності"</string>
+ <string name="power_label" msgid="7699720321491287839">"Живлення"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Опції живлення"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Нещодавні додатки"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Заблокований екран"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Швидкі налаштування"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Сповіщення"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Знімок екрана"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Зробити знімок екрана"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Збільшити гучність"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Зменшити гучність"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Збільшити яскравість"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Зменшити яскравість"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Перейти на попередній екран"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Перейти на наступний екран"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"За допомогою великого екранного меню спеціальних можливостей можна заблокувати пристрій, змінювати гучність і яскравість, робити знімки екрана та багато іншого."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Керування пристроєм за допомогою великого меню"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Налаштування \"Меню спеціальних можливостей\""</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Великі кнопки"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Збільшити розмір кнопок меню спеціальних можливостей"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Довідка"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Яскравість: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Гучність музики: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ur/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ur/strings.xml
new file mode 100644
index 0000000..b1f2f3b
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ur/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"ایکسیسبیلٹی مینو"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"اپنے آلے کو کنٹرول کرنے کے لیے ایکسیسبیلٹی مینو ایک بڑا آن اسکرین مینو فراہم کرتا ہے۔ آپ اپنا آلہ مقفل، والیوم اور چمک کو کنٹرول، اسکرین شاٹ لینے کے ساتھ اور مزید بہت کچھ کر سکتے ہیں۔"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"اسسٹنٹ"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"ایکسیسبیلٹی ترتیبات"</string>
+ <string name="volume_label" msgid="3682221827627150574">"والیوم"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"والیوم کے کنٹرولز"</string>
+ <string name="power_label" msgid="7699720321491287839">"پاور"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"پاور کے اختیارات"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"حالیہ ایپس"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"مقفل اسکرین"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"فوری ترتیبات"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"اطلاعات"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"اسکرین شاٹ"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"اسکرین شاٹ لیں"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"والیوم بڑھانے کا بٹن"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"والیوم کم کرنے کا بٹن"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"چمک بڑھانے کا بٹن"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"چمک کم کرنے کا بٹن"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"پچھلی اسکرین پر جائیں"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"اگلی اسکرین پر جائیں"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"اپنے آلے کو کنٹرول کرنے کے لیے ایکسیسبیلٹی مینو ایک بڑا آن اسکرین مینو فراہم کرتا ہے۔ آپ اپنا آلہ مقفل، والیوم اور چمک کو کنٹرول، اسکرین شاٹ لینے کے ساتھ اور مزید بہت کچھ کر سکتے ہیں۔"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"بڑے مینو کے ذریعے آلہ کنٹرول کریں"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"ایکسیسبیلٹی مینو کی ترتیبات"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"بڑے بٹنز"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"ایکسیسبیلٹی مینو بٹنز کا سائز بڑھائیں"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"مدد"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"چمک %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"موسیقی کا والیوم %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-uz/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uz/strings.xml
new file mode 100644
index 0000000..63af1b1
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-uz/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Maxsus imkoniyatlar menyusi"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Maxsus imkoniyatlar menyusi telefoningizni boshqarish uchun katta menyuni taqdim etadi. Bu menyu orqali telefonni qulflash, ovoz balandligi va yorqinlikni boshqarish, skrinshotlar olish kabi amallarni bajarish mumkin."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Maxsus imkoniyatlar sozlamalari"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Tovush balandligi"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Tovush balandligi tugmalari"</string>
+ <string name="power_label" msgid="7699720321491287839">"Quvvat"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Quvvat parametrlari"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Yaqinda ishlatilgan ilovalar"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Ekran qulfi"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Tezkor sozlamalar"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Bildirishnomalar"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Skrinshot"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Skrinshot olish"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Tovushni balandlatish"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Tovushni pasaytirish"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Yorqinlikni oshirish"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Yorqinlikni pasaytirish"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Avvalgi ekranni ochish"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Keyingi ekranni ochish"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Maxsus imkoniyatlar menyusi telefoningizni boshqarish uchun katta menyuni taqdim etadi. Bu menyu orqali telefonni qulflash, ovoz balandligi va yorqinlikni boshqarish, skrinshotlar olish kabi amallarni bajarish mumkin."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Katta menyu orqali qurilmani boshqarish"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Maxsus imkoniyatlar menyusi sozlamalari"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Katta tugmalar"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Maxsus imkoniyatlar menyusi tugmalarini kattalashtirish"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Yordam"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Yorqinlik: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Musiqa tovushi balandligi: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-vi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-vi/strings.xml
new file mode 100644
index 0000000..e22a9ab
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-vi/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Trình đơn hỗ trợ tiếp cận"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Menu Hỗ trợ tiếp cận cung cấp một trình đơn lớn trên màn hình dùng để điều khiển thiết bị. Bạn có thể khóa thiết bị, điều chỉnh âm lượng và độ sáng, chụp ảnh màn hình và nhiều chức năng khác."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Trợ lý"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Cài đặt hỗ trợ tiếp cận"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Âm lượng"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Điều khiển âm lượng"</string>
+ <string name="power_label" msgid="7699720321491287839">"Nguồn"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Tùy chọn nút Nguồn"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Ứng dụng gần đây"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Màn hình khóa"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Cài đặt nhanh"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Thông báo"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Ảnh chụp màn hình"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Chụp ảnh màn hình"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Tăng âm lượng"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Giảm âm lượng"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Tăng độ sáng"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Giảm độ sáng"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Chuyển đến màn hình trước"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Chuyển đến màn hình tiếp theo"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Menu Hỗ trợ tiếp cận cung cấp một trình đơn lớn trên màn hình dùng để điều khiển thiết bị. Bạn có thể khóa thiết bị, điều chỉnh âm lượng và độ sáng, chụp ảnh màn hình và nhiều việc khác."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Điều khiển thiết bị qua trình đơn lớn"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Cài đặt Trình đơn Hỗ trợ tiếp cận"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Nút lớn"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Tăng kích thước của các nút trong Trình đơn Hỗ trợ tiếp cận"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Trợ giúp"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Độ sáng <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Âm lượng nhạc <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rCN/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..e34f8d5
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rCN/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"无障碍功能菜单"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"无障碍功能菜单可在屏幕上提供一个大号的菜单,供您控制设备,比如锁定设备、控制音量和亮度、截取屏幕快照等。"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"无障碍设置"</string>
+ <string name="volume_label" msgid="3682221827627150574">"音量"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"音量控件"</string>
+ <string name="power_label" msgid="7699720321491287839">"电源"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"电源选项"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"最近用过的应用"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"锁定屏幕"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"快捷设置"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"通知"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"屏幕截图"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"抓取屏幕截图"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"调高音量"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"调低音量"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"调高亮度"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"调低亮度"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"转到上一个屏幕"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"转到下一个屏幕"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"无障碍功能菜单可在屏幕上提供一个大号的菜单,供您控制设备,比如锁定设备、控制音量和亮度、截取屏幕快照等。"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"使用大菜单控制设备"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"无障碍功能菜单设置"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"大按钮"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"增大无障碍功能菜单按钮的大小"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"帮助"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"亮度:<xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"音乐音量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..e08e52f3
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rHK/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙功能選單"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便您鎖定裝置、控制音量和亮度、擷取螢幕畫面及執行其他功能。"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"無障礙功能設定"</string>
+ <string name="volume_label" msgid="3682221827627150574">"音量"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"音量控制項"</string>
+ <string name="power_label" msgid="7699720321491287839">"電源"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"電源選項"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"最近使用的應用程式"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"螢幕鎖定"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"快速設定"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"通知"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"螢幕擷取畫面"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"擷取螢幕擷圖"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"調高音量"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"調低音量"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"調光亮度"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"調暗亮度"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"前往上一個畫面"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"前往下一個畫面"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"「無障礙功能選單」是螢幕上的大型選單,用來控制裝置,方便您鎖定裝置、控制音量和亮度、擷取螢幕畫面及執行其他功能。"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"透過大型選單控制裝置"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"無障礙功能選單設定"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"大按鈕"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"放大「無障礙功能選單按鈕」"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"說明"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"光暗度:<xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"音樂音量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..a6dfe71
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙選單"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"無障礙工具選單是螢幕上的大型選單,可用來操控裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕畫面,以及執行其他功能。"</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"無障礙設定"</string>
+ <string name="volume_label" msgid="3682221827627150574">"音量"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"音量控制項"</string>
+ <string name="power_label" msgid="7699720321491287839">"電源"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"電源選項"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"最近使用的應用程式"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"螢幕鎖定"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"快速設定"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"通知"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"螢幕截圖"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"擷取螢幕畫面"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"調高音量"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"調低音量"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"調高亮度"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"調低亮度"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"返回上一個畫面"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"前往下一個畫面"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"無障礙工具選單是螢幕上的大型選單,可用來操控裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕畫面,以及執行其他功能。"</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"透過大型選單操控裝置"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"無障礙選單設定"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"大型按鈕"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"放大無障礙選單按鈕"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"說明"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"亮度 <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"音樂音量 <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zu/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zu/strings.xml
new file mode 100644
index 0000000..bf70957
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zu/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Imenyu yokufinyeleleka"</string>
+ <string name="accessibility_menu_intro" msgid="3164193281544042394">"Imenyu yokufinyelela inikezela ngemenyu enkulu esesikrinini ukuze ulawule idivayisi yakho. Ungakhiya idivayisi yakho, ulawule ivolumu nokukhanya, uthathe izithombe-skrini, nokuningi."</string>
+ <string name="assistant_label" msgid="6796392082252272356">"Umsizi"</string>
+ <!-- no translation found for assistant_utterance (65509599221141377) -->
+ <skip />
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Izilungiselelo zokufinyelela"</string>
+ <string name="volume_label" msgid="3682221827627150574">"Ivolumu"</string>
+ <string name="volume_utterance" msgid="408291570329066290">"Izilawuli zevolumu"</string>
+ <string name="power_label" msgid="7699720321491287839">"Amandla"</string>
+ <string name="power_utterance" msgid="7444296686402104807">"Izinketho zamandla"</string>
+ <string name="recent_apps_label" msgid="6583276995616385847">"Izinhlelo zokusebenza zakamuva"</string>
+ <string name="lockscreen_label" msgid="648347953557887087">"Khiya isikrini"</string>
+ <string name="quick_settings_label" msgid="2999117381487601865">"Izilungiselelo ezisheshayo"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"Izaziso"</string>
+ <string name="screenshot_label" msgid="863978141223970162">"Isithombe-skrini"</string>
+ <string name="screenshot_utterance" msgid="1430760563401895074">"Thatha isithombe-skrini"</string>
+ <string name="volume_up_label" msgid="8592766918780362870">"Ivolumu phezulu"</string>
+ <string name="volume_down_label" msgid="8574981863656447346">"Ivolumu iphansi"</string>
+ <string name="brightness_up_label" msgid="8010753822854544846">"Ukukhanya kuphezulu"</string>
+ <string name="brightness_down_label" msgid="7115662941913272072">"Ukukhanya kuphansi"</string>
+ <string name="previous_button_content_description" msgid="840869171117765966">"Hamba kusikrini sangaphambilini"</string>
+ <string name="next_button_content_description" msgid="6810058269847364406">"Iya kusikrini esilandelayo"</string>
+ <string name="accessibility_menu_description" msgid="4458354794093858297">"Imenyu yokufinyelela inikezela ngemenyu enkulu esesikrinini ukuze ulawule idivayisi yakho. Ungakhiya idivayisi yakho, ulawule ivolumu nokukhanya, uthathe izithombe-skrini, nokuningi."</string>
+ <string name="accessibility_menu_summary" msgid="340071398148208130">"Lawula idivayisi ngemenyu enkulu"</string>
+ <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Izilungiselelo zemenyu yokufinyelela"</string>
+ <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Izinkinobho ezinkulu"</string>
+ <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Khulisa usayizi wezinkinobho zemenyu yokufinyelela"</string>
+ <string name="pref_help_title" msgid="6871558837025010641">"Usizo"</string>
+ <string name="brightness_percentage_label" msgid="7391554573977867369">"Ukukhanya <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+ <string name="music_volume_percentage_label" msgid="398635599662604706">"Ivolumu yomculo <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
+</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
index 81fa8e6..46bd611 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
@@ -13,10 +13,6 @@
<string name="assistant_utterance">Assistant</string>
<!-- String defining the label for the accessibility settings button -->
<string name="a11y_settings_label">Accessibility Settings</string>
- <!-- String defining the label for the volume button -->
- <string name="volume_label">Volume</string>
- <!-- String defining utterance for the volume button for screen readers -->
- <string name="volume_utterance">Volume controls</string>
<!-- String defining the label for the power button -->
<string name="power_label">Power</string>
<!-- String defining utterance for the power button for screen readers -->
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back.xml b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
index ee40262..6c34655 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_back.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
@@ -15,13 +15,13 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
+ android:width="20dp"
+ android:height="20dp"
android:autoMirrored="true"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:viewportWidth="20"
+ android:viewportHeight="20">
<path
android:fillColor="?attr/singleToneColor"
- android:pathData="M6.49,14.86c-0.66-0.39-0.66-1.34,0-1.73l6.02-3.53l5.89-3.46C19.11,5.73,20,6.26,20,7.1V14v6.9 c0,0.84-0.89,1.37-1.6,0.95l-5.89-3.46L6.49,14.86z" />
+ android:pathData="M15.5417 1.66669C15.1833 1.66669 14.8417 1.76669 14.5333 1.94169L3.21667 8.74169C2.775 9.00002 2.5 9.48335 2.5 10C2.5 10.5167 2.775 11 3.21667 11.2584L14.5333 18.05C14.8417 18.2334 15.1833 18.325 15.5417 18.325C16.625 18.325 17.5 17.45 17.5 16.3667V3.62502C17.5 2.54169 16.625 1.66669 15.5417 1.66669Z" />
</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
index da23937..8b2a58a 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -15,12 +15,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
<path
android:fillColor="?attr/singleToneColor"
- android:pathData="M 14 7 C 17.8659932488 7 21 10.1340067512 21 14 C 21 17.8659932488 17.8659932488 21 14 21 C 10.1340067512 21 7 17.8659932488 7 14 C 7 10.1340067512 10.1340067512 7 14 7 Z" />
+ android:pathData="M10.0001 18.3334C5.40008 18.3334 1.66675 14.6 1.66675 10C1.66675 5.40002 5.40008 1.66669 10.0001 1.66669C14.6001 1.66669 18.3334 5.40002 18.3334 10C18.3334 14.6 14.6001 18.3334 10.0001 18.3334Z" />
</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
index 6b038d1..6ff3ec3 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
@@ -15,12 +15,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
<path
android:fillColor="?attr/singleToneColor"
- android:pathData="M19.9,21.5H8.1c-0.88,0-1.6-0.72-1.6-1.6V8.1c0-0.88,0.72-1.6,1.6-1.6h11.8c0.88,0,1.6,0.72,1.6,1.6v11.8 C21.5,20.78,20.78,21.5,19.9,21.5z" />
+ android:pathData="M4.47634 2.5H15.5241C16.6164 2.5 17.5002 3.38382 17.5002 4.4761V15.5239C17.5002 16.6162 16.6164 17.5 15.5241 17.5H4.47634C3.38407 17.5 2.50024 16.6162 2.50024 15.5239V4.4761C2.50024 3.38382 3.38407 2.5 4.47634 2.5Z" />
</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_container.xml b/packages/SystemUI/res/layout/dream_overlay_container.xml
index 8e83b4a..ae0a937 100644
--- a/packages/SystemUI/res/layout/dream_overlay_container.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_container.xml
@@ -25,11 +25,12 @@
android:id="@+id/dream_overlay_content"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_marginTop="@dimen/dream_overlay_container_margin_top"
- android:layout_marginEnd="@dimen/dream_overlay_container_margin_end"
- android:layout_marginBottom="@dimen/dream_overlay_container_margin_bottom"
- android:layout_marginStart="@dimen/dream_overlay_container_margin_start"
-
+ android:paddingTop="@dimen/dream_overlay_container_padding_top"
+ android:paddingEnd="@dimen/dream_overlay_container_padding_end"
+ android:paddingBottom="@dimen/dream_overlay_container_padding_bottom"
+ android:paddingStart="@dimen/dream_overlay_container_padding_start"
+ android:clipToPadding="false"
+ android:clipChildren="false"
app:layout_constraintTop_toBottomOf="@id/dream_overlay_status_bar"
app:layout_constraintBottom_toBottomOf="parent"
/>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 4f7d099..4d6c2022 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -321,7 +321,8 @@
<RelativeLayout
android:id="@+id/bottom_buttons"
android:layout_width="match_parent"
- android:layout_height="60dp"
+ android:layout_height="wrap_content"
+ android:minHeight="60dp"
android:gravity="center_vertical"
android:paddingStart="4dp"
android:paddingEnd="4dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 8e4cc43..73a77bd 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktiveer USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Kom meer te wete"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skermkiekie"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Verleng Ontsluiting is gedeaktiveer"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"het \'n prent gestuur"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Stoor tans skermkiekie..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Stoor tans skermskoot in werkprofiel …"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrole bygevoeg.}other{# kontroles bygevoeg.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Voeg <xliff:g id="APPNAME">%s</xliff:g> by?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> kan kies watter kontroles en inhoud hier gewys word."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Verwyder kontroles vir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"As gunsteling gemerk; posisie <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"wysig"</string>
<string name="add" msgid="81036585205287996">"Voeg by"</string>
<string name="manage_users" msgid="1823875311934643849">"Bestuur gebruikers"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Sleep na verdeelde skerm word nie vir hierdie kennisgewing gesteun nie."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Sleep na verdeelde skerm word nie vir hierdie kennisgewing gesteun nie"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑fi onbeskikbaar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 2991118..4159cca 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -871,8 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ይታከል?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> የትኛዎቹ መቆጣጠሪያዎች እና ይዘት እዚህ እንደሚታዩ መምረጥ ይችላል።"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"የ<xliff:g id="APPNAME">%s</xliff:g> መቆጣጠሪያዎች ይወገዱ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"አርትዕ"</string>
<string name="add" msgid="81036585205287996">"አክል"</string>
<string name="manage_users" msgid="1823875311934643849">"ተጠቃሚዎችን ያስተዳድሩ"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ይህ ማሳወቂያ ወደ Splitscreen መጎተትን አይደግፍም።"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ይህ ማሳወቂያ ወደ የተከፈለ ማያ ገጽ መጎተትን አይደግፍም"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi አይገኝም"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"የቅድሚያ ሁነታ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 53c0bee..17c3d0f 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"تفعيل USB"</string>
<string name="learn_more" msgid="4690632085667273811">"مزيد من المعلومات"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"لقطة شاشة"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"تم إيقاف ميزة Extend Unlock."</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"أرسَل صورة"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"جارٍ حفظ لقطة الشاشة..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"جارٍ حفظ لقطة الشاشة في الملف الشخصي للعمل…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"التعديل"</string>
<string name="add" msgid="81036585205287996">"إضافة"</string>
<string name="manage_users" msgid="1823875311934643849">"إدارة المستخدمين"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"لا يتيح هذا الإشعار السحب لتقسيم الشاشة."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"لا يتيح هذا الإشعار إمكانية السحب لتقسيم الشاشة."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"شبكة Wi‑Fi غير متاحة"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"وضع الأولوية"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d076ed4..95cfcb4 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB সক্ষম কৰক"</string>
<string name="learn_more" msgid="4690632085667273811">"অধিক জানক"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"স্ক্ৰীনশ্বট"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock অক্ষম কৰা আছে"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"কৰ্মস্থানৰ প্ৰ’ফাইলত স্ক্ৰীনশ্বট ছেভ কৰি থকা হৈছে…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ দিবনে?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g>এ ইয়াত কোনবোৰ নিয়ন্ত্ৰণ আৰু সমল দেখুওৱা হ’ব সেয়া বাছনি কৰিব পাৰে।"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>ৰ নিয়ন্ত্ৰণ আঁতৰাবনে?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"সম্পাদনা কৰক"</string>
<string name="add" msgid="81036585205287996">"যোগ দিয়ক"</string>
<string name="manage_users" msgid="1823875311934643849">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"এই জাননীটোৱে টানি আনি এৰাৰ পৰা বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"এই জাননীটোৱে বিভাজিত স্ক্ৰীনলৈ টানি আনি এৰাৰ সুবিধাটো সমৰ্থন নকৰে"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ৱাই-ফাই উপলব্ধ নহয়"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"অগ্ৰাধিকাৰ ম’ড"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e625577..7e26882 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-ni aktiv edin"</string>
<string name="learn_more" msgid="4690632085667273811">"Ətraflı məlumat"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skrinşot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock deaktiv edilib"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"şəkil göndərdi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinşot yadda saxlanır..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"İş profili skrinşotu saxlanılır…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# nizamlayıcı əlavə edilib.}other{# nizamlayıcı əlavə edilib.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Silinib"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> əlavə edilsin?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> burada göstəriləcək nizamlayıcı və kontenti seçə bilər."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> nizamlayıcıları silinsin?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Sevimlilərə əlavə edilib, sıra: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"redaktə"</string>
<string name="add" msgid="81036585205287996">"Əlavə edin"</string>
<string name="manage_users" msgid="1823875311934643849">"İstifadəçiləri idarə edin"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildiriş Ayrılmış ekrana sürüşdürməyi dəstəkləmir."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Bu bildiriş bölünmüş ekrana sürüşdürməyi dəstəkləmir"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi əlçatan deyil"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritet rejimi"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 4f122ec..6f36211 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snimak ekrana"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Produženo otključavanje je onemogućeno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Čuvanje snimka ekrana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Snimak ekrana se čuva na poslovnom profilu…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li da dodate <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> može da odabere koje kontrole i sadržaj se prikazuju ovde."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Želite da uklonite kontrole za <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"izmenite"</string>
<string name="add" msgid="81036585205287996">"Dodaj"</string>
<string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ovo obaveštenje ne podržava prevlačenje na podeljeni ekran"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi nije dostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni režim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 4018983..0b30428 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Уключыць USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Даведацца больш"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Здымак экрана"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Функцыя падоўжанай разблакіроўкі адключана"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"адпраўлены відарыс"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Захаванне скрыншота..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Захаванне здымка экрана ў працоўны профіль…"</string>
@@ -1067,7 +1066,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"змяніць"</string>
<string name="add" msgid="81036585205287996">"Дадаць"</string>
<string name="manage_users" msgid="1823875311934643849">"Кіраванне карыстальнікамі"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Гэта апавяшчэнне нельга перацягнуць на падзелены экран."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сетка Wi‑Fi недаступная"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Прыярытэтны рэжым"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6a65303..dd4c4e8 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Активиране на USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Научете повече"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Екранна снимка"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Удълженото отключване е деактивирано"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"изпратено изображение"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Екранната снимка се запазва..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Екранната снимка се запазва в служебния профил…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се добави ли <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> може да избира съдържанието и контролите, които да се показват тук."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Да се премахнат ли контролите за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"редактиране"</string>
<string name="add" msgid="81036585205287996">"Добавяне"</string>
<string name="manage_users" msgid="1823875311934643849">"Управление на потребителите"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Това известие не поддържа плъзгане за разделяне на екрана."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi не е налице"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 373f6b4..1d7d607 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ করবেন?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"এখানে কোন কন্ট্রোল ও কন্টেন্ট দেখানো হবে <xliff:g id="APPNAME">%s</xliff:g> তা বেছে নিতে পারবে।"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>-এর জন্য নিয়ন্ত্রণ সরিয়ে দেবেন?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"এডিট করতে"</string>
<string name="add" msgid="81036585205287996">"যোগ করুন"</string>
<string name="manage_users" msgid="1823875311934643849">"ব্যবহারকারীদের ম্যানেজ করুন"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"স্প্লিটস্ক্রিন মোডে এই বিজ্ঞপ্তি টেনে আনা যাবে না।"</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ওয়াই-ফাই উপলভ্য নেই"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"প্রায়োরিটি মোড"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 627531a..62eafb4 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -69,7 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snimak ekrana"</string>
- <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Produljivanje otključavanja onemogućeno"</string>
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Produženo otključavanje je onemogućeno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Spašavanje snimka ekrana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pohranjivanje snimka ekrana na radni profil…"</string>
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Aplikacija <xliff:g id="APPNAME">%s</xliff:g> može odabrati koje će kontrole i sadržaj prikazivati ovdje."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ukloniti kontrole za aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u omiljeno, pozicija <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"uredi"</string>
<string name="add" msgid="81036585205287996">"Dodaj"</string>
<string name="manage_users" msgid="1823875311934643849">"Upravljajte korisnicima"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ovo obavještenje ne podržava prevlačenje na podijeljeni ekran."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ovo obavještenje ne podržava prevlačenje na podijeljeni ekran"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi je nedostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Način rada Prioriteti"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index faae1a8..42649d1 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activa l\'USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Més informació"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Captura de pantalla"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desactivat"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviat una imatge"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"S\'està desant la captura de pantalla..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"S\'està desant la captura al perfil de treball…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{S\'han afegit # controls.}other{S\'han afegit # controls.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vols afegir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> pot triar quins controls i continguts es mostren aquí."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vols suprimir els controls per a <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Afegeix"</string>
<string name="manage_users" msgid="1823875311934643849">"Gestiona els usuaris"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Aquesta notificació no es pot arrossegar a la pantalla dividida."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Aquesta notificació no es pot arrossegar a la pantalla dividida"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritat"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 560ee4d..13b87f1 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivovat USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Další informace"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snímek obrazovky"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Prodloužení odemknutí deaktivováno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odesílá obrázek"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ukládání snímku obrazovky..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukládání snímku obrazovky do pracovního profilu…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"upravit"</string>
<string name="add" msgid="81036585205287996">"Přidat"</string>
<string name="manage_users" msgid="1823875311934643849">"Správa uživatelů"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 5f7fc69..815b402 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivér USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Få flere oplysninger"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold oplåst er deaktiveret"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendte et billede"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Gemmer screenshot..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gemmer screenshot på din arbejdsprofil…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"redigere"</string>
<string name="add" msgid="81036585205287996">"Tilføj"</string>
<string name="manage_users" msgid="1823875311934643849">"Administrer brugere"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Denne notifikation kan ikke trækkes til en opdelt skærm."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Denne notifikation kan ikke trækkes til en opdelt skærm"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Ingen tilgængelig Wi-Fi-forbindelse"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tilstanden Prioritet"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index caac9eb..a3dcf62 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB aktivieren"</string>
<string name="learn_more" msgid="4690632085667273811">"Weitere Informationen"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"„Extend Unlock“ deaktiviert"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"Bild gesendet"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Screenshot wird gespeichert..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Screenshot wird in Arbeitsprofil gespeichert…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> hinzufügen?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> darf auswählen, welche Einstellungen und Inhalte hier angezeigt werden."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Einstellungen für <xliff:g id="APPNAME">%s</xliff:g> entfernen?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"bearbeiten"</string>
<string name="add" msgid="81036585205287996">"Hinzufügen"</string>
<string name="manage_users" msgid="1823875311934643849">"Nutzer verwalten"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Diese Benachrichtigung lässt sich nicht auf einen geteilten Bildschirm ziehen."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN nicht verfügbar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritätsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 7dd3593..4c76e17 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Προστέθηκε # στοιχείο ελέγχου.}other{Προστέθηκαν # στοιχεία ελέγχου.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Προσθήκη <xliff:g id="APPNAME">%s</xliff:g>;"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Η εφαρμογή <xliff:g id="APPNAME">%s</xliff:g> μπορεί να επιλέξει τα στοιχεία ελέγχου και το περιεχόμενο που θα εμφανίζεται εδώ."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Κατάργηση στοιχείων ελέγχου για την εφαρμογή <xliff:g id="APPNAME">%s</xliff:g>;"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Προστέθηκε στα αγαπημένα, στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"επεξεργασία"</string>
<string name="add" msgid="81036585205287996">"Προσθήκη"</string>
<string name="manage_users" msgid="1823875311934643849">"Διαχείριση χρηστών"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Αυτή η ειδοποίηση δεν υποστηρίζει τη μεταφορά με σύρσιμο για χρήση του διαχωρισμού οθόνης."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Αυτή η ειδοποίηση δεν υποστηρίζει τη μεταφορά με σύρσιμο για τον διαχωρισμό οθόνης"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Το Wi‑Fi δεν είναι διαθέσιμο"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Λειτουργία προτεραιότητας"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index f2e0c26..8086828 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"This notification does not support dragging to split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index fb72218..c53db18 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Splitscreen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"This notification does not support dragging to split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index f2e0c26..8086828 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"This notification does not support dragging to split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index f2e0c26..8086828 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Split screen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"This notification does not support dragging to split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 5ea3dd6..11c7db8 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Add"</string>
<string name="manage_users" msgid="1823875311934643849">"Manage users"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"This notification does not support dragging to Splitscreen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"This notification does not support dragging to split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi unavailable"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 9853c9b..8f3fc6f 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Se agregó # control.}many{Se agregaron # controles.}other{Se agregaron # controles.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitados"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Quieres agregar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> puede elegir qué controles y contenido mostrar aquí."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"¿Quieres quitar los controles para <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está en favoritos en la posición <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Agregar"</string>
<string name="manage_users" msgid="1823875311934643849">"Administrar usuarios"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no admite arrastrar entre pantallas divididas."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"La red Wi-Fi no está disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioridad"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2e5b4d1..a4c4dd0 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Habilitar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Más información"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Captura de pantalla"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock inhabilitado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ha enviado una imagen"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Guardando captura..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Guardando captura en el perfil de trabajo…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Añadir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> puede elegir qué controles y contenido se muestran aquí."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"¿Quitar los controles de <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Añadir"</string>
<string name="manage_users" msgid="1823875311934643849">"Gestionar usuarios"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación no se puede arrastrar a la pantalla dividida."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificación no se puede arrastrar a la pantalla dividida"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi no disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo prioritario"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
@@ -1089,7 +1087,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"¿Permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir el acceso una vez"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permitir"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, aún podrá acceder a sus propios registros. El fabricante de tu dispositivo aún puede acceder a algunos registros o información de tu dispositivo."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, podrá seguir accediendo a sus propios registros. Es posible que el fabricante del dispositivo pueda acceder a algunos registros o información de tu dispositivo. Más información"</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Más información"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Más información en <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index d0f3a46..1288060 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Luba USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Lisateave"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Ekraanipilt"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock on keelatud"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"saatis kujutise"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Kuvatõmmise salvestamine ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekraanipildi salvestamine tööprofiilile …"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Kas lisada <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Rakendus <xliff:g id="APPNAME">%s</xliff:g> saab valida, millised juhtelemendid ja milline sisu siin kuvatakse."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Kas soovite rakenduse <xliff:g id="APPNAME">%s</xliff:g> juhtelemendid eemaldada?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -895,9 +893,9 @@
<string name="controls_dialog_message" msgid="342066938390663844">"Soovitas <xliff:g id="APP">%s</xliff:g>"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"Seade on lukustatud"</string>
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Kas soovite seadmete juhtelemente lukustuskuval kuvada ja kasutada?"</string>
- <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Võite lukustuskuvale oma väliste seadmete juhtelemendid lisada.\n\nTeie seadmerakendus võib võimaldada teil teatud seadmeid ilma telefoni või tahvelarvutit avamata hallata.\n\nSaate igal ajal seadetes muudatusi teha."</string>
- <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kas soovite seadmeid lukustuskuva kaudu hallata?"</string>
- <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Võite teatud seadmeid ilma telefoni või tahvelarvutit avamata hallata. Teie seadmerakendus määrab, milliseid seadmeid saab sel viisil hallata."</string>
+ <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Võite lukustuskuvale oma väliste seadmete juhtelemendid lisada.\n\nTeie seadmerakendus võib võimaldada teil teatud seadmeid ilma telefoni või tahvelarvutit avamata juhtida.\n\nSaate igal ajal seadetes muudatusi teha."</string>
+ <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kas soovite seadmeid lukustuskuva kaudu juhtida?"</string>
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Võite teatud seadmeid ilma telefoni või tahvelarvutit avamata juhtida. Teie seadmerakendus määrab, milliseid seadmeid saab sel viisil juhtida."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Tänan, ei"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Jah"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-kood sisaldab tähti või sümboleid"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"muutmine"</string>
<string name="add" msgid="81036585205287996">"Lisa"</string>
<string name="manage_users" msgid="1823875311934643849">"Kasutajate haldamine"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"See märguanne ei toeta jagatud ekraanikuvale lohistamist."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi pole saadaval"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režiim Prioriteetne"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 05c08c8..4873d88 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Gaitu USB ataka"</string>
<string name="learn_more" msgid="4690632085667273811">"Lortu informazio gehiago"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Pantaila-argazkia"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desgaitu da desblokeatze luzatua"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"erabiltzaileak irudi bat bidali du"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Pantaila-argazkia gordetzen…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pantaila-argazkia laneko profilean gordetzen…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Kontrolatzeko # aukera gehitu da.}other{Kontrolatzeko # aukera gehitu dira.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> gehitu nahi duzu?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Hemen zein kontrolatzeko aukera eta eduki agertzen diren aukera dezake <xliff:g id="APPNAME">%s</xliff:g> aplikazioak."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> kontrolatzeko aukerak kendu nahi dituzu?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>. gogokoa da"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editatzeko"</string>
<string name="add" msgid="81036585205287996">"Gehitu"</string>
<string name="manage_users" msgid="1823875311934643849">"Kudeatu erabiltzaileak"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Jakinarazpen hau ezin da arrastatu pantaila zatitura."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Jakinarazpen hau ezin da arrastatu pantaila zatitura"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi-konexioa ez dago erabilgarri"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Lehentasun modua"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 9c9620f..f62ab77 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"فعال کردن USB"</string>
<string name="learn_more" msgid="4690632085667273811">"بیشتر بدانید"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"نماگرفت"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock غیرفعال شده است"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"تصویری ارسال کرد"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"درحال ذخیره نماگرفت…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"درحال ذخیره کردن نماگرفت در نمایه کاری…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> افزوده شود؟"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> میتواند انتخاب کند چه کنترلها و محتوایی اینجا نشان داده شود."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"کنترلهای <xliff:g id="APPNAME">%s</xliff:g> برداشته شود؟"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافهشده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ویرایش کردن"</string>
<string name="add" msgid="81036585205287996">"افزودن"</string>
<string name="manage_users" msgid="1823875311934643849">"مدیریت کاربران"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"این اعلان از تنظیم کشیدن برای دو نیمه کردن صفحه پشتیبانی نمیکند."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi دردسترس نیست"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"حالت اولویت"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a4fd4d9..e478bd2 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ota USB käyttöön"</string>
<string name="learn_more" msgid="4690632085667273811">"Lue lisää"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Kuvakaappaus"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock poistettu käytöstä"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"lähetti kuvan"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Tallennetaan kuvakaappausta..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Kuvakaappausta tallennetaan työprofiiliin…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"muokkaa"</string>
<string name="add" msgid="81036585205287996">"Lisää"</string>
<string name="manage_users" msgid="1823875311934643849">"Ylläpidä käyttäjiä"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ilmoitus ei tue jaetulle näytölle vetämistä."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ilmoitus ei tue jaetulle näytölle vetämistä"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ei ole saatavilla"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tärkeät-tila"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 8f4c897..bb26ad4 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activer l\'USB"</string>
<string name="learn_more" msgid="4690632085667273811">"En savoir plus"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Capture d\'écran"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock désactivée"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement capture écran…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sauv. de la capture dans le profil prof. en cours…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"modifier"</string>
<string name="add" msgid="81036585205287996">"Ajouter"</string>
<string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Cette notification ne prend pas en charge le partage d\'écran par glissement."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Cette notification ne prend pas en charge l\'écran partagé par glissement"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi non disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode priorité"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 16140d0..fb0d42c 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activer le port USB"</string>
<string name="learn_more" msgid="4690632085667273811">"En savoir plus"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Capture d\'écran"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Déverrouillage étendu désactivé"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a envoyé une image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Enregistrement de la capture d\'écran…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Enregistrement de capture d\'écran dans profil pro…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# commandes ajoutées.}other{# commandes ajoutées.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g> ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> peut choisir les commandes et contenus à afficher ici."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Supprimer les commandes pour <xliff:g id="APPNAME">%s</xliff:g> ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"modifier"</string>
<string name="add" msgid="81036585205287996">"Ajouter"</string>
<string name="manage_users" msgid="1823875311934643849">"Gérer les utilisateurs"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Impossible de faire glisser cette notification vers l\'écran partagé."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode Prioritaire"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 815029b..ac8acde 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Máis información"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Facer captura"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desactivouse o desbloqueo ampliado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou unha imaxe"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Gardando captura de pantalla…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Gardando captura de pantalla no perfil de traballo"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Engadir"</string>
<string name="manage_users" msgid="1823875311934643849">"Xestionar usuarios"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificación non pode arrastrarse á pantalla dividida."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificación non pode arrastrarse á pantalla dividida"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A wifi non está dispoñible"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 3d32c7f..1267200 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ચાલુ કરો"</string>
<string name="learn_more" msgid="4690632085667273811">"વધુ જાણો"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"સ્ક્રીનશૉટ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlockની સુવિધા બંધ કરવામાં આવી"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"છબી મોકલી"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"સ્ક્રીનશોટ સાચવી રહ્યું છે…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ઑફિસની પ્રોફાઇલમાં સ્ક્રીનશૉટ સાચવી રહ્યાં છીએ…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# નિયંત્રણ ઉમેર્યું.}one{# નિયંત્રણ ઉમેર્યું.}other{# નિયંત્રણ ઉમેર્યા.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ઉમેરીએ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> પસંદ કરી શકે છે કે કયા નિયંત્રણો અને કન્ટેન્ટ અહીં બતાવવામાં આવે."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> માટે નિયંત્રણો કાઢી નાખીએ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"મનપસંદમાં ઉમેર્યું, સ્થાન <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ફેરફાર કરો"</string>
<string name="add" msgid="81036585205287996">"ઉમેરો"</string>
<string name="manage_users" msgid="1823875311934643849">"વપરાશકર્તાઓને મેનેજ કરો"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"આ નોટિફિકેશન તેને સ્પ્લિટસ્ક્રીનમાં ખેંચવાની સુવિધાને સપોર્ટ કરતું નથી."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"આ નોટિફિકેશન તેને વિભાજિત સ્ક્રીનમાં ખેંચવાની સુવિધાને સપોર્ટ કરતું નથી"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"પ્રાધાન્યતા મોડ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 5a88b5d..f1ff616 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"यूएसबी चालू करें"</string>
<string name="learn_more" msgid="4690632085667273811">"ज़्यादा जानें"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रीनशॉट"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock की सुविधा बंद की गई"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"एक इमेज भेजी गई"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रीनशॉट सहेजा जा रहा है..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"स्क्रीनशॉट, वर्क प्रोफ़ाइल में सेव किया जा रहा है…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ना है?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> यह चुन सकता है कि इस पैनल पर कौनसे कंट्रोल और कॉन्टेंट दिखे."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> के लिए कंट्रोल हटाने हैं?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"बदलाव करें"</string>
<string name="add" msgid="81036585205287996">"जोड़ें"</string>
<string name="manage_users" msgid="1823875311934643849">"उपयोगकर्ताओं को मैनेज करें"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"इस सूचना को स्प्लिट स्क्रीन मोड में, खींचा और छोड़ा नहीं जा सकता."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"इस सूचना को स्प्लिट स्क्रीन मोड में, खींचा और छोड़ा नहीं जा सकता"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाई-फ़ाई उपलब्ध नहीं है"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c89a590..4ece4b6 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"U aplikaciji <xliff:g id="APPNAME">%s</xliff:g> možete odabrati koje se kontrole i sadržaj ovdje prikazuju."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ukloniti kontrole za aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u favorite"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u favorite, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"uredi"</string>
<string name="add" msgid="81036585205287996">"Dodaj"</string>
<string name="manage_users" msgid="1823875311934643849">"Upravljanje korisnicima"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ova obavijest ne podržava povlačenje na podijeljeni zaslon."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ova obavijest ne podržava povlačenje na podijeljeni zaslon."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nije dostupan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetni način rada"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 96931df..8d38e1f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB engedélyezése"</string>
<string name="learn_more" msgid="4690632085667273811">"Részletek"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Képernyőkép"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock letiltva"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"képet küldött"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Képernyőkép mentése..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Képernyőkép mentése a munkaprofilba…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# vezérlő hozzáadva.}other{# vezérlő hozzáadva.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Hozzáadja a(z) <xliff:g id="APPNAME">%s</xliff:g> alkalmazást?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"A(z) <xliff:g id="APPNAME">%s</xliff:g> eldöntheti, milyen vezérlőket és tartalmakat jelenít meg itt."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Eltávolítja a(z) <xliff:g id="APPNAME">%s</xliff:g> vezérlőit?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Hozzáadva a kedvencekhez <xliff:g id="NUMBER">%d</xliff:g>. helyen"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"szerkesztés"</string>
<string name="add" msgid="81036585205287996">"Hozzáadás"</string>
<string name="manage_users" msgid="1823875311934643849">"Felhasználók kezelése"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Az értesítés nem támogatja a megosztott képernyőre való áthúzást."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Az értesítés nem támogatja az osztott képernyőre való áthúzást."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"A Wi‑Fi nem áll rendelkezésre"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritás mód"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index b852836..ed4b312 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Միացնել USB-ն"</string>
<string name="learn_more" msgid="4690632085667273811">"Իմանալ ավելին"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Սքրինշոթ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"«Երկարացնել կողպումը» գործառույթն անջատված է"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"պատկեր է ուղարկվել"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Սքրինշոթը պահվում է..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Սքրինշոթը պահվում է աշխատանքային պրոֆիլում…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"փոփոխել"</string>
<string name="add" msgid="81036585205287996">"Ավելացնել"</string>
<string name="manage_users" msgid="1823875311934643849">"Օգտատերերի կառավարում"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Այս ծանուցումը հնարավոր չէ քաշել տրոհված էկրանի մեկ հատվածից մյուսը։"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Այս ծանուցումը հնարավոր չէ քաշել տրոհված էկրանի մեկ հատվածից մյուսը"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi-ը հասանելի չէ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Առաջնահերթության ռեժիմ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index e293b9b..72f7158 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktifkan USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Pelajari lebih lanjut"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock dinonaktifkan"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"mengirim gambar"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Menyimpan screenshot..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Menyimpan screenshot ke profil kerja …"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> dapat memilih kontrol dan konten yang ditampilkan di sini."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Hapus kontrol untuk <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"mengedit"</string>
<string name="add" msgid="81036585205287996">"Tambahkan"</string>
<string name="manage_users" msgid="1823875311934643849">"Kelola pengguna"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Notifikasi ini tidak mendukung fitur tarik ke Layar terpisah."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Notifikasi ini tidak mendukung fitur tarik ke layar terpisah"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi tidak tersedia"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mode prioritas"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 1e6b6ed..d84e544 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Virkja USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Frekari upplýsingar"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skjámynd"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Slökkt á Extend Unlock"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sendi mynd"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Vistar skjámynd…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Vistar skjámynd á vinnusnið…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Viltu bæta <xliff:g id="APPNAME">%s</xliff:g> við?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> getur valið hvaða stýringar og efni birtist hér."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Fjarlægja stýringar fyrir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"breyta"</string>
<string name="add" msgid="81036585205287996">"Bæta við"</string>
<string name="manage_users" msgid="1823875311934643849">"Stjórna notendum"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Þessi tilkynning styður ekki að draga yfir á skiptan skjá."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Þessi tilkynning styður ekki að draga yfir á skiptan skjá."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi ekki tiltækt"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Forgangsstilling"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a3da707..d103e41 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -799,7 +799,7 @@
<string name="slice_permission_deny" msgid="6870256451658176895">"Rifiuta"</string>
<string name="auto_saver_title" msgid="6873691178754086596">"Tocca per programmare il Risparmio energetico"</string>
<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="no_auto_saver_action" msgid="7467924389609773835">"No, grazie"</string>
<string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump heap SysUI"</string>
<string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"In uso"</string>
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
@@ -1066,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"modificare"</string>
<string name="add" msgid="81036585205287996">"Aggiungi"</string>
<string name="manage_users" msgid="1823875311934643849">"Gestisci utenti"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Non è possibile trascinare questa notifica tra le due parti dello schermo diviso."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Non è possibile trascinare questa notifica tra le due parti dello schermo diviso"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi non disponibile"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modalità Priorità"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 3a2e040..8c9667c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"הפעלת USB"</string>
<string name="learn_more" msgid="4690632085667273811">"מידע נוסף"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"צילום מסך"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"התכונה \'הרחבה של ביטול הנעילה\' מושבתת"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"נשלחה תמונה"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"המערכת שומרת את צילום המסך..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"צילום המסך נשמר בפרופיל העבודה…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}one{נוספו # אמצעי בקרה.}two{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"הוסר"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"להוסיף את <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"האפליקציה <xliff:g id="APPNAME">%s</xliff:g> יכולה לבחור אילו אמצעי בקרה ותוכן להראות כאן."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"להסיר את אמצעי הבקרה של <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כמועדף, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"עריכה"</string>
<string name="add" msgid="81036585205287996">"הוספה"</string>
<string name="manage_users" msgid="1823875311934643849">"ניהול משתמשים"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ההתראה הזו לא תומכת בגרירה למסך מפוצל."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ההתראה הזו לא תומכת בגרירה למסך מפוצל"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi לא זמין"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 550a19e..2fb65a8 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1066,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"編集"</string>
<string name="add" msgid="81036585205287996">"追加"</string>
<string name="manage_users" msgid="1823875311934643849">"ユーザーの管理"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"この通知は、分割画面へのドラッグがサポートされていません。"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"この通知は、分割画面へのドラッグをサポートしていません"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi を利用できません"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先順位モード"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 8e95488..67852ea 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{დაემატა მართვის # საშუალება.}other{დაემატა მართვის # საშუალება.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"გსურთ <xliff:g id="APPNAME">%s</xliff:g>-ის დამატება?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g>-ს შეუძლია აირჩიოს, მართვის რომელი საშუალებები და კონტენტი უნდა გამოჩნდეს აქ."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ამოიშალოს <xliff:g id="APPNAME">%s</xliff:g>-ის მართვის საშუალებები?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"რჩეულებშია, პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"რედაქტირება"</string>
<string name="add" msgid="81036585205287996">"დამატება"</string>
<string name="manage_users" msgid="1823875311934643849">"მომხმარებლების მართვა"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ამ შეტყობინების გადათრევა გაყოფილ ეკრანებს შორის არ არის მხარდაჭერილი."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ამ შეტყობინების გადათრევა გაყოფილ ეკრანებს შორის არ არის მხარდაჭერილი."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi მიუწვდომელია"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"პრიორიტეტული რეჟიმი"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 08b4879..fb0688d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB қосу"</string>
<string name="learn_more" msgid="4690632085667273811">"Толығырақ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Скриншот"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Құлыпты ашық ұстау функциясы өшірілді."</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"сурет жіберілді"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Скриншотты сақтауда…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Скриншот жұмыс профиліне сақталып жатыр…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосу керек пе?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасы осы жерде көрсетілетін басқару құралдары мен контентті таңдай алады."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасының басқару элементтері жойылсын ба?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"өзгерту"</string>
<string name="add" msgid="81036585205287996">"Қосу"</string>
<string name="manage_users" msgid="1823875311934643849">"Пайдаланушыларды басқару"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Бұл хабарландыруды бөлінген экранға сүйреп апару мүмкін емес."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Бұл хабарландыруды бөлінген экранға сүйреп апару мүмкін емес."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi қолжетімсіз"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Басымдық режимі"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 9cdd5c0..1106ef2 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"បើក USB"</string>
<string name="learn_more" msgid="4690632085667273811">"ស្វែងយល់បន្ថែម"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"រូបថតអេក្រង់"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"បានបិទការដោះសោបន្ថែម"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"បានផ្ញើរូបភាព"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"កំពុងរក្សាទុករូបថតអេក្រង់..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"កំពុងរក្សាទុករូបថតអេក្រង់ទៅកម្រងព័ត៌មានការងារ…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូលការគ្រប់គ្រង #។}other{បានបញ្ចូលការគ្រប់គ្រង #។}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"បញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> ឬ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> អាចជ្រើសរើសឱ្យការគ្រប់គ្រង និងខ្លឹមសារណាខ្លះបង្ហាញនៅទីនេះ។"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ដកការគ្រប់គ្រងសម្រាប់ <xliff:g id="APPNAME">%s</xliff:g> ចេញឬ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជាសំណព្វ"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជាសំណព្វ ទីតាំងទី <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"កែ"</string>
<string name="add" msgid="81036585205287996">"បញ្ចូល"</string>
<string name="manage_users" msgid="1823875311934643849">"គ្រប់គ្រងអ្នកប្រើប្រាស់"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ការជូនដំណឹងនេះមិនអាចឱ្យអូសដើម្បីបំបែកអេក្រង់បានទេ។"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ការជូនដំណឹងនេះមិនអាចឱ្យអូសដើម្បីបំបែកអេក្រង់បានទេ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ត្រូវបានបិទ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"មុខងារអាទិភាព"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់ម៉ោងរោទ៍"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index fcdf34d..f1c2b918 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="learn_more" msgid="4690632085667273811">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ಎಕ್ಸ್ಟೆಂಡ್ ಅನ್ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ಗೆ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ನಿಯಂತ್ರಣವನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}one{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}other{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ಅನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> ಯಾವ ಕಂಟ್ರೋಲ್ಗಳು ಮತ್ತು ವಿಷಯವನ್ನು ತೋರಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಬಹುದು."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> ಗಾಗಿ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆಗೆದುಹಾಕಬೇಕೆ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ಮೆಚ್ಚಲಾಗಿರುವುದು, ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="add" msgid="81036585205287996">"ಸೇರಿಸಿ"</string>
<string name="manage_users" msgid="1823875311934643849">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡುವುದನ್ನು ಈ ಅಧಿಸೂಚನೆಯು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡುವುದನ್ನು ಈ ನೋಟಿಫಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ಆದ್ಯತೆ ಮೋಡ್"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e339524..d1f9a2d 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB 사용"</string>
<string name="learn_more" msgid="4690632085667273811">"자세히 알아보기"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"스크린샷"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"잠금 해제 연장 사용 중지됨"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"이미지 보냄"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"캡쳐화면 저장 중..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"직장 프로필에 스크린샷 저장 중…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>을(를) 추가할까요?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g>에서 여기에 표시되는 컨트롤 및 콘텐츠를 선택할 수 있습니다."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> 컨트롤을 삭제할까요?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"수정"</string>
<string name="add" msgid="81036585205287996">"추가"</string>
<string name="manage_users" msgid="1823875311934643849">"사용자 관리"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"드래그하여 화면을 분할하는 기능이 지원되지 않는 알림입니다."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"드래그하여 화면을 분할하는 기능이 지원되지 않는 알림입니다."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi를 이용할 수 없습니다."</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"우선순위 모드입니다."</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 77fddef..4693950 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB’ни иштетүү"</string>
<string name="learn_more" msgid="4690632085667273811">"Кененирээк"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Скриншот"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"\"Кулпуну ачуу\" функциясы өчүрүлдү"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"сүрөт жөнөттү"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Скриншот сакталууда..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Скриншот жумуш профилине сакталууда…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> кошулсунбу?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> бул жерде көрсөтүлө турган башкаруу элементтерин жана контентти тандай алат."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> башкаруу элементтери өчүрүлсүнбү?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"түзөтүү"</string>
<string name="add" msgid="81036585205287996">"Кошуу"</string>
<string name="manage_users" msgid="1823875311934643849">"Колдонуучуларды башкаруу"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Бул билдирмени бөлүнгөн экранда сүйрөөгө болбойт."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Бул билдирмени бөлүнгөн экранда сүйрөөгө болбойт."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi жеткиликсиз"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Маанилүү сүйлөшүүлөр режими"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 541b418..21f4312 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ເປີດໃຊ້ USB"</string>
<string name="learn_more" msgid="4690632085667273811">"ສຶກສາເພີ່ມເຕີມ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ພາບໜ້າຈໍ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ຂະຫຍາຍການປົດລັອກຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ສົ່ງຮູບແລ້ວ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ກຳລັງບັນທຶກພາບໜ້າຈໍ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ກຳລັງບັນທຶກຮູບໜ້າຈໍໃສ່ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}other{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"ເພີ່ມ <xliff:g id="APPNAME">%s</xliff:g> ບໍ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> ສາມາດເລືອກໄດ້ວ່າການຄວບຄຸມ ແລະ ເນື້ອຫາໃດຈະສະແດງຢູ່ບ່ອນນີ້."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ລຶບການຄວບຄຸມສຳລັບ <xliff:g id="APPNAME">%s</xliff:g> ອອກບໍ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ, ຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ແກ້ໄຂ"</string>
<string name="add" msgid="81036585205287996">"ເພີ່ມ"</string>
<string name="manage_users" msgid="1823875311934643849">"ຈັດການຜູ້ໃຊ້"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ການແຈ້ງເຕືອນນີ້ບໍ່ຮອງຮັບການລາກໄປໃສ່ Splitscreen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ການແຈ້ງເຕືອນນີ້ບໍ່ຮອງຮັບການລາກເພື່ອແບ່ງໜ້າຈໍ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ບໍ່ສາມາດໃຊ້ Wi‑Fi ໄດ້"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ໂໝດຄວາມສຳຄັນ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 38fe1c7..326f11b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Įgalinti USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Sužinokite daugiau"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Ekrano kopija"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Išplėstinis atrakinimas išjungtas"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"išsiuntė vaizdą"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Išsaugoma ekrano kopija..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Išsaugoma ekrano kopija darbo profilyje…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pridėtas # valdiklis.}one{Pridėtas # valdiklis.}few{Pridėti # valdikliai.}many{Pridėta # valdiklio.}other{Pridėta # valdiklių.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Pašalinta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Pridėti „<xliff:g id="APPNAME">%s</xliff:g>“?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"„<xliff:g id="APPNAME">%s</xliff:g>“ gali pasirinkti, kuriuos valdiklius ir turinį čia rodyti."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Pašalinti „<xliff:g id="APPNAME">%s</xliff:g>“ valdiklius?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Įtraukta į mėgstamiausius"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Įtraukta į mėgstamiausius, padėtis: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"redaguoti"</string>
<string name="add" msgid="81036585205287996">"Pridėti"</string>
<string name="manage_users" msgid="1823875311934643849">"Tvarkyti naudotojus"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Šio pranešimo vilkimas išskaidyto ekrano režimu nepalaikomas."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Šio pranešimo vilkimas išskaidyto ekrano režimu nepalaikomas"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"„Wi‑Fi“ ryšys nepasiekiamas"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteto režimas"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 6b03a03..d7e99d4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Iespējot USB portu"</string>
<string name="learn_more" msgid="4690632085667273811">"Uzzināt vairāk"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Ekrānuzņēmums"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Paildzinātā atbloķēšana ir atspējota"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"nosūtīts attēls"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Notiek ekrānuzņēmuma saglabāšana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Notiek ekrānuzņēmuma saglabāšana darba profilā…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pievienota # vadīkla.}zero{Pievienotas # vadīklas.}one{Pievienota # vadīkla.}other{Pievienotas # vadīklas.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vai pievienot lietotni <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> var izvēlēties, kuras vadīklas un saturu šeit rādīt."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vai noņemt vadīklas lietotnei <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pievienota izlasei, <xliff:g id="NUMBER">%d</xliff:g>. pozīcija"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"rediģētu"</string>
<string name="add" msgid="81036585205287996">"Pievienot"</string>
<string name="manage_users" msgid="1823875311934643849">"Pārvaldīt lietotājus"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Šis paziņojums neatbalsta vilkšanu uz dalīto ekrānu."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Šis paziņojums neatbalsta vilkšanu uz sadalīto ekrānu."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nav pieejams"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritātes režīms"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 940b6191..1948796 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Овозможи USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Дознајте повеќе"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Слика од екранот"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"„Продолженото отклучување“ е оневозможено"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"испрати слика"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Сликата на екранот се зачувува..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Се зачувува слика од екранот на вашиот работен профил…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додадена е # контрола.}one{Додадени се # контрола.}other{Додадени се # контроли.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Отстранета"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се додаде <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> може да избере кои контроли и содржини се прикажуваат овде."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Да се отстранат контролите за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Омилена"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Омилена, позиција <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"измени"</string>
<string name="add" msgid="81036585205287996">"Додај"</string>
<string name="manage_users" msgid="1823875311934643849">"Управувајте со корисниците"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Известувањево не поддржува влечење на поделен екран."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Известувањево не поддржува влечење на поделен екран"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi е недостапна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетен режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 2597fcd..0a36380 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="learn_more" msgid="4690632085667273811">"കൂടുതലറിയുക"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"സ്ക്രീൻഷോട്ട്"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ചിത്രം അയച്ചു"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കുന്നു…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# നിയന്ത്രണം ചേർത്തു.}other{# നിയന്ത്രണങ്ങൾ ചേർത്തു.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്തു"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ചേർക്കണോ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"ഏതൊക്കെ നിയന്ത്രണങ്ങളും ഉള്ളടക്കവും ഇവിടെ ദൃശ്യമാകണമെന്ന് <xliff:g id="APPNAME">%s</xliff:g> എന്നതിന് തിരഞ്ഞെടുക്കാനാകും."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> എന്നതിനുള്ള നിയന്ത്രണങ്ങൾ നീക്കം ചെയ്യണോ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"പ്രിയപ്പെട്ടതാക്കി, സ്ഥാനം <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"എഡിറ്റ് ചെയ്യുക"</string>
<string name="add" msgid="81036585205287996">"ചേർക്കുക"</string>
<string name="manage_users" msgid="1823875311934643849">"ഉപയോക്താക്കളെ മാനേജ് ചെയ്യുക"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"സ്പ്ലിറ്റ് സ്ക്രീനിലേക്ക് വലിച്ചിടുന്നതിനെ ഈ അറിയിപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"സ്പ്ലിറ്റ് സ്ക്രീനിലേക്ക് വലിച്ചിടുന്നതിനെ ഈ അറിയിപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"വൈഫൈ ലഭ്യമല്ല"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"മുൻഗണനാ മോഡ്"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index cd5bdfd..759218a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-г идэвхжүүлэх"</string>
<string name="learn_more" msgid="4690632085667273811">"Нэмэлт мэдээлэл авах"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Дэлгэцийн зураг дарах"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock-г идэвхгүй болгосон"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"зураг илгээсэн"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Дэлгэцийн агшинг хадгалж байна…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Дэлгэцийн агшныг ажлын профайлд хадгалж байна…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Хассан"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үү?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> аль хяналт болон контент энд харагдахыг сонгож болно."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>-н тохиргоог хасах уу?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"засах"</string>
<string name="add" msgid="81036585205287996">"Нэмэх"</string>
<string name="manage_users" msgid="1823875311934643849">"Хэрэглэгчдийг удирдах"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Энэ мэдэгдэл нь Дэлгэцийг хуваах горим руу чирэхийг дэмждэггүй."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Энэ мэдэгдэл нь дэлгэцийг хуваах горим руу чирэхийг дэмждэггүй"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi боломжгүй"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Чухал горим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index ea86fae..c0605a8 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -145,10 +145,10 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
- <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन दाबा."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी दाबा."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी दाबा."</string>
- <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन दाबा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
+ <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
<string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
@@ -335,12 +335,12 @@
<string name="notification_tap_again" msgid="4477318164947497249">"उघडण्यासाठी पुन्हा टॅप करा"</string>
<string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
- <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन दाबा"</string>
+ <string name="keyguard_unlock_press" msgid="9140109453735019209">"उघडण्यासाठी अनलॉक करा आयकन प्रेस करा"</string>
<string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी वर स्वाइप करा."</string>
- <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
- <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी दाबा."</string>
- <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी दाबा."</string>
- <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरा ओळखला आहे. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
+ <string name="keyguard_face_successful_unlock_press" msgid="25520941264602588">"चेहऱ्याने अनलॉक केले. उघडण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_1" msgid="5715461103913071474">"चेहऱ्याने अनलॉक केले आहे. उघडण्यासाठी प्रेस करा."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_2" msgid="8310787946357120406">"चेहरा ओळखला आहे. उघडण्यासाठी प्रेस करा."</string>
+ <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरा ओळखला आहे. उघडण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
<string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"चेहऱ्याने अनलॉक केले आहे"</string>
<string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"चेहरा ओळखला आहे"</string>
<string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्वाइप करा"</string>
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# नियंत्रण जोडले आहे.}other{# नियंत्रणे जोडली आहेत.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> जोडायचे आहे का?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> हे येथे कोणती नियंत्रणे आणि आशय दाखवावा ते निवडू शकते."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> साठी नियंत्रणे काढून टाकायची आहेत का?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"आवडले, स्थान <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"संपादित करा"</string>
<string name="add" msgid="81036585205287996">"जोडा"</string>
<string name="manage_users" msgid="1823875311934643849">"वापरकर्ते व्यवस्थापित करा"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ही सूचना स्प्लिटस्क्रीनवर ड्रॅग करण्याला सपोर्ट करत नाही."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ही सूचना स्प्लिट स्क्रीनवर ड्रॅग करण्याला सपोर्ट करत नाही"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"वाय-फाय उपलब्ध नाही"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राधान्य मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 1158287..ce9aa40 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Dayakan USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Ketahui lebih lanjut"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Tangkapan skrin"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Lanjutkan Buka Kunci dilumpuhkan"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"menghantar imej"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Menyimpan tangkapan skrin..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Menyimpan tangkapan skrin ke profil kerja…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g>boleh memilih kawalan dan kandungan yang dipaparkan di sini."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Alih keluar kawalan untuk <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edit"</string>
<string name="add" msgid="81036585205287996">"Tambah"</string>
<string name="manage_users" msgid="1823875311934643849">"Urus pengguna"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Pemberitahuan ini tidak menyokong penyeretan ke Skrin pisah."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Pemberitahuan ini tidak menyokong penyeretan kepada skrin pisah"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi dimatikan"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Mod keutamaan"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index c110097..0194c77 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ကို ဖွင့်ရန်"</string>
<string name="learn_more" msgid="4690632085667273811">"ပိုမိုလေ့လာရန်"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"‘တိုးချဲ့ဖွင့်ခြင်း’ ပိတ်ထားသည်"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ပုံပို့ထားသည်"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား သိမ်းဆည်းပါမည်"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"အလုပ်ပရိုဖိုင်တွင် ဖန်သားပြင်ဓာတ်ပုံ သိမ်းနေသည်…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်မလား။"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> သည် ဤနေရာတွင်ပြသည့် သတ်မှတ်ချက်နှင့် အကြောင်းအရာများကို ရွေးနိုင်သည်။"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> အတွက် သတ်မှတ်ချက်များ ဖယ်ရှားမလား။"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"တည်းဖြတ်ရန်"</string>
<string name="add" msgid="81036585205287996">"ထည့်ရန်"</string>
<string name="manage_users" msgid="1823875311934643849">"အသုံးပြုသူများ စီမံရန်"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ဤအကြောင်းကြားချက်သည် ‘မျက်နှာပြင်ခွဲ၍ပြသမှု’ သို့ ဖိဆွဲခြင်းကို မပံ့ပိုးပါ။"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ဤအကြောင်းကြားချက်သည် ‘မျက်နှာပြင် ခွဲ၍ပြသခြင်း’ သို့ ဖိဆွဲမှုကို မပံ့ပိုးပါ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi မရပါ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ဦးစားပေးမုဒ်"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index c6a665a..f0da4e9 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Slå på USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Finn ut mer"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skjermdump"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock er slått av"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har sendt et bilde"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermdumpen …"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermdumpen i jobbprofilen …"</string>
@@ -1067,7 +1066,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"redigere"</string>
<string name="add" msgid="81036585205287996">"Legg til"</string>
<string name="manage_users" msgid="1823875311934643849">"Administrer brukere"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Dette varselet støtter ikke at du drar det til en delt skjerm."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi er utilgjengelig"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteringsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 621fdab..c451853 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB सक्षम पार्नुहोस्"</string>
<string name="learn_more" msgid="4690632085667273811">"थप जान्नुहोस्"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रिनसट"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock अफ गरिएको छ"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"कुनै छवि पठाइयो"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रिनसट बचत गर्दै…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलमा स्क्रिनसट सेभ गरिँदै छ…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कन्ट्रोल हालियो।}other{# वटा कन्ट्रोल हालियो।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> हाल्ने हो?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> ले यहाँ कुन कुन कन्ट्रोल र सामग्री देखाउने भन्ने कुरा छनौट गर्न सक्छ।"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> का सेटिङ हटाउने हो?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"मन पराइएका कुराहरूको <xliff:g id="NUMBER">%d</xliff:g> औँ स्थानमा"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"सम्पादन गर्नुहोस्"</string>
<string name="add" msgid="81036585205287996">"हाल्नुहोस्"</string>
<string name="manage_users" msgid="1823875311934643849">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"यो सूचना ड्र्याग गरेर स्प्लिटस्क्रिनमा लैजान मिल्दैन।"</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi उपलब्ध छैन"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"प्राथमिकता मोड"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3b8a957..88faab4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB aanzetten"</string>
<string name="learn_more" msgid="4690632085667273811">"Meer informatie"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Ontgrendelen verlengen uitgezet"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"heeft een afbeelding gestuurd"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Screenshot opslaan..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Screenshot opslaan in werkprofiel…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# bedieningselement toegevoegd.}other{# bedieningselementen toegevoegd.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> toevoegen?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> kan kiezen welke bedieningselementen en content hier worden getoond."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Bedieningselementen voor <xliff:g id="APPNAME">%s</xliff:g> verwijderen?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Gemarkeerd als favoriet, positie <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"bewerken"</string>
<string name="add" msgid="81036585205287996">"Toevoegen"</string>
<string name="manage_users" msgid="1823875311934643849">"Gebruikers beheren"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Deze melding biedt geen ondersteuning voor slepen naar het gesplitste scherm."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Deze melding biedt geen ondersteuning voor slepen naar het gesplitste scherm"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi niet beschikbaar"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioriteitsmodus"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 98ae465..a576ac5 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="learn_more" msgid="4690632085667273811">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ସ୍କ୍ରିନ୍ସଟ୍ ନିଅନ୍ତୁ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlockକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ଏକ ଛବି ପଠାଯାଇଛି"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ କରାଯାଉଛି…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ ସ୍କ୍ରିନସଟ ସେଭ କରାଯାଉଛି…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରିବେ?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"ଏଠାରେ କେଉଁ ନିୟନ୍ତ୍ରଣ ଏବଂ ବିଷୟବସ୍ତୁ ଦେଖାଯିବ ତାହା <xliff:g id="APPNAME">%s</xliff:g> ବାଛିପାରିବ।"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> ପାଇଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ କାଢ଼ି ଦେବେ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ଏଡିଟ କରନ୍ତୁ"</string>
<string name="add" msgid="81036585205287996">"ଯୋଗ କରନ୍ତୁ"</string>
<string name="manage_users" msgid="1823875311934643849">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟସ୍କ୍ରିନକୁ ଡ୍ରାଗ କରିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ଏହି ବିଜ୍ଞପ୍ତି ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ଟାଣିବାକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ପ୍ରାଥମିକତା ମୋଡ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ebdcd0c..acc9339 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB ਚਾਲੂ ਕਰੋ"</string>
<string name="learn_more" msgid="4690632085667273811">"ਹੋਰ ਜਾਣੋ"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ਚਿੱਤਰ ਭੇਜਿਆ ਗਿਆ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸੁਰੱਖਿਅਤ ਕਰ ਰਿਹਾ ਹੈ…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ਸੰਪਾਦਨ ਕਰੋ"</string>
<string name="add" msgid="81036585205287996">"ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="manage_users" msgid="1823875311934643849">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ਇਹ ਸੂਚਨਾ ਸਪਲਿਟ ਸਕ੍ਰੀਨ \'ਤੇ ਘਸੀਟਣ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ।"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ਇਹ ਸੂਚਨਾ ਸਪਲਿਟ ਸਕ੍ਰੀਨ \'ਤੇ ਘਸੀਟਣ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ ਹੈ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ਤਰਜੀਹੀ ਮੋਡ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 37eb638..078db24 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodać aplikację <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Aplikacja <xliff:g id="APPNAME">%s</xliff:g> może wybrać elementy sterujące i treści, które się tu pojawią."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Usunąć elementy sterujące aplikacji <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"edytować"</string>
<string name="add" msgid="81036585205287996">"Dodaj"</string>
<string name="manage_users" msgid="1823875311934643849">"Zarządzaj użytkownikami"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"To powiadomienie nie obsługuje dzielenia ekranu przez przeciąganie."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Sieć Wi‑Fi niedostępna"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Tryb priorytetowy"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 498428e..6b78aa7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Adicionar"</string>
<string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificação não pode ser arrastada para a tela dividida"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 59e6cc4..8595ed0 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}many{# controlos adicionados.}other{# controlos adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"A app <xliff:g id="APPNAME">%s</xliff:g> pode escolher que controlos e conteúdos são apresentados aqui."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controlos para a app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Adicionar"</string>
<string name="manage_users" msgid="1823875311934643849">"Gerir utilizadores"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não pode ser arrastada para o ecrã dividido."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificação não pode ser arrastada para o ecrã dividido"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo Prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 498428e..6b78aa7 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> pode escolher quais controles e conteúdos aparecem aqui."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editar"</string>
<string name="add" msgid="81036585205287996">"Adicionar"</string>
<string name="manage_users" msgid="1823875311934643849">"Gerenciar usuários"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Esta notificação não tem suporte para ser arrastada para a tela dividida."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Esta notificação não pode ser arrastada para a tela dividida"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi indisponível"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modo de prioridade"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ae0939f..c915522 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Activează USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Mai multe"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Captură de ecran"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Funcția Extend Unlock este dezactivată"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"a trimis o imagine"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Se salvează captura de ecran..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Se salvează captura în profilul de serviciu…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S-a adăugat # comandă.}few{S-au adăugat # comenzi.}other{S-au adăugat # de comenzi.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adaugi <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> poate să aleagă comenzile și conținutul care se afișează aici."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Elimini comenzile pentru <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Marcată ca preferată, poziția <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"editează"</string>
<string name="add" msgid="81036585205287996">"Adaugă"</string>
<string name="manage_users" msgid="1823875311934643849">"Gestionează utilizatorii"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Notificarea nu acceptă tragerea pe ecranul împărțit."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Notificarea nu acceptă tragerea pe ecranul împărțit"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi indisponibil"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modul Prioritate"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 244bdf7..42fe056 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Включить USB-порт"</string>
<string name="learn_more" msgid="4690632085667273811">"Подробнее"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Скриншот"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Функция \"Отложить блокировку\" отключена"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"отправлено изображение"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Сохранение..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Сохранение скриншота в рабочем профиле…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавлен # элемент управления.}one{Добавлен # элемент управления.}few{Добавлено # элемента управления.}many{Добавлено # элементов управления.}other{Добавлено # элемента управления.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Удалено"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Добавить приложение \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Приложение \"<xliff:g id="APPNAME">%s</xliff:g>\" может выбирать, какой контент и настройки будут здесь показываться."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Удалить приложение \"<xliff:g id="APPNAME">%s</xliff:g>\" с панели управления устройствами?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Добавлено в избранное на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"изменить"</string>
<string name="add" msgid="81036585205287996">"Добавить"</string>
<string name="manage_users" msgid="1823875311934643849">"Управление пользователями"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Это уведомление нельзя перетаскивать между частями разделенного экрана."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Это уведомление нельзя перетаскивать между частями разделенного экрана."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Сеть Wi‑Fi недоступна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим приоритета"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 61a5ce5..5522178 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB සබල කරන්න"</string>
<string name="learn_more" msgid="4690632085667273811">"තවත් දැන ගන්න"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"තිර රුව"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"දිගු අගුළු හැරීම අබල කර ඇත"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"රූපයක් එවන ලදී"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"තිර රුව සුරැකෙමින් පවතී…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"කාර්යාල පැතිකඩ වෙත තිර රුව සුරකිමින්…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"සංස්කරණය"</string>
<string name="add" msgid="81036585205287996">"එක් කරන්න"</string>
<string name="manage_users" msgid="1823875311934643849">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"මෙම දැනුම්දීම බෙදුම් තිරය වෙත ඇද ගෙන යාමට සහාය නොදක්වයි."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"මෙම දැනුම්දීම බෙදුම් තිරය වෙත ඇද ගෙන යාමට සහාය නොදක්වයි."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ලබා ගත නොහැකිය"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ප්රමුඛතා ප්රකාරය"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 276f51f..7210689 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Povoliť USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Ďalšie informácie"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snímka obrazovky"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Predĺžené odomknutie je vypnuté"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"odoslal(a) obrázok"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Prebieha ukladanie snímky obrazovky..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ukladá sa snímka obrazovky do pracovného profilu…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Bol pridaný # ovládací prvok.}few{Boli pridané # ovládacie prvky.}many{# controls added.}other{Bolo pridaných # ovládacích prvkov.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Chcete pridať aplikáciu <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> môže vybrať, ktoré ovládacie prvky a obsah sa tu majú zobrazovať."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Chcete odstrániť ovládanie aplikácie <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pridané medzi obľúbené, pozícia <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"upraviť"</string>
<string name="add" msgid="81036585205287996">"Pridať"</string>
<string name="manage_users" msgid="1823875311934643849">"Spravovať používateľov"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Toto upozornenie nepodporuje presun na rozdelenú obrazovku"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nie je k dispozícii"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Režim priority"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 9736284..7bdb979 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogoči USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Več o tem"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Posnetek zaslona"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Podaljšanje časa odklenjenosti je onemogočeno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslal(-a) sliko"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Shranjevanje posnetka zaslona ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Shranjevanje posnetka zaslona v delovni profil …"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite dodati aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Aplikacija <xliff:g id="APPNAME">%s</xliff:g> lahko izbere, kateri kontrolniki in vsebine so prikazani tukaj."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Želite odstraniti kontrolnike za aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"urejanje"</string>
<string name="add" msgid="81036585205287996">"Dodaj"</string>
<string name="manage_users" msgid="1823875311934643849">"Upravljanje uporabnikov"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"To obvestilo ne podpira vlečenja v razdeljen zaslon."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"To obvestilo ne podpira vlečenja v razdeljen zaslon."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ni na voljo."</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prednostni način"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 02f9638..71da15c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivizo USB-në"</string>
<string name="learn_more" msgid="4690632085667273811">"Mëso më shumë"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Pamja e ekranit"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"\"Shkyçja e zgjeruar\" u çaktivizua"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"dërgoi një imazh"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Po ruan pamjen e ekranit…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pamja e ekranit po ruhet te profili i punës…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{U shtua # kontroll.}other{U shtuan # kontrolle.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"E hequr"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Të shtohet <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> mund të zgjedhë se cilat kontrolle dhe përmbajtje shfaqen këtu."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Të hiqen kontrollet për <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"E shtuar te të preferuarat, pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"për të modifikuar"</string>
<string name="add" msgid="81036585205287996">"Shto"</string>
<string name="manage_users" msgid="1823875311934643849">"Menaxho përdoruesit"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ky njoftim nuk mbështet zvarritjen në \"Ekranin e ndarë\"."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ky njoftim nuk mbështet zvarritjen tek ekrani i ndarë"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi nuk ofrohet"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Modaliteti \"Me përparësi\""</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ed99913..6136c36 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Омогући USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Сазнајте више"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Снимак екрана"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Продужено откључавање је онемогућено"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"је послао/ла слику"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Чување снимка екрана..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Снимак екрана се чува на пословном профилу…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Желите ли да додате <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> може да одабере које контроле и садржај се приказују овде."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Желите да уклоните контроле за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"измените"</string>
<string name="add" msgid="81036585205287996">"Додај"</string>
<string name="manage_users" msgid="1823875311934643849">"Управљаjте корисницима"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Ово обавештење не подржава превлачење на подељени екран."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Ово обавештење не подржава превлачење на подељени екран"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WiFi није доступан"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Приоритетни режим"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 2809b3b..f359ae9 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Aktivera USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Läs mer"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skärmbild"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock har inaktiverats"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har skickat en bild"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skärmbilden sparas ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sparar skärmbild i jobbprofilen …"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vill du lägga till <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> kan välja vilka kontroller och vilket innehåll som visas här."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vill du ta bort inställningarna för <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"redigera"</string>
<string name="add" msgid="81036585205287996">"Lägg till"</string>
<string name="manage_users" msgid="1823875311934643849">"Hantera användare"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Det går inte att dra den här aviseringen till delad skärm."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Det går inte att dra den här aviseringen till delad skärm"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wifi är inte tillgängligt"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritetsläge"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 056a8a8..6973c89 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Washa kipengele cha USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Pata maelezo zaidi"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Picha ya skrini"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Kipengele cha Kuongeza muda wa Kutofunga Skrini kimezimwa"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"imetuma picha"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Inahifadhi picha ya skrini..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Inahifadhi picha ya skrini kwenye wasifu wa kazini…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ungependa kuweka <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> inaweza kuchagua ni vidhibiti na maudhui yapi yatakayoonekana hapa."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ungependa kuondoa vidhibiti vya <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ubadilishe"</string>
<string name="add" msgid="81036585205287996">"Weka"</string>
<string name="manage_users" msgid="1823875311934643849">"Dhibiti watumiaji"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Arifa hii hairuhusu kuburuta kwenye Skrini iliyogawanyika."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi haipatikani"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Hali ya kipaumbele"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 49ace23..e32f28a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBயை இயக்கு"</string>
<string name="learn_more" msgid="4690632085667273811">"மேலும் அறிக"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ஸ்கிரீன்ஷாட்"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"நீண்டநேர அன்லாக் அம்சம் முடக்கப்பட்டது"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"படம் அனுப்பப்பட்டது"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ஸ்க்ரீன் ஷாட்டைச் சேமிக்கிறது…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"பணிக் கணக்கில் ஸ்கிரீன்ஷாட் சேமிக்கப்படுகிறது…"</string>
@@ -1067,7 +1066,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"திருத்தும்"</string>
<string name="add" msgid="81036585205287996">"சேர்"</string>
<string name="manage_users" msgid="1823875311934643849">"பயனர்களை நிர்வகித்தல்"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"பிரிக்கப்பட்ட திரைக்குள் இந்த அறிவிப்பை இழுத்துவிட முடியாது."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"வைஃபை கிடைக்கவில்லை"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"முன்னுரிமைப் பயன்முறை"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 9fe3d5c..894298a 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USBని ప్రారంభించండి"</string>
<string name="learn_more" msgid="4690632085667273811">"మరింత తెలుసుకోండి"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"స్క్రీన్షాట్"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"అన్లాక్ను పొడిగించడం డిజేబుల్ చేయబడింది"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ఇమేజ్ను పంపారు"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"స్క్రీన్షాట్ను సేవ్ చేస్తోంది…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"స్క్రీన్షాట్ను వర్క్ ప్రొఫైల్కు సేవ్ చేస్తోంది…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>ను జోడించాలా?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> ఇక్కడ ఏ కంట్రోల్స్, కంటెంట్ కనిపించాలో ఎంచుకోగలదు."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> కోసం కంట్రోల్స్ను తీసివేయాలా?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ఎడిట్"</string>
<string name="add" msgid="81036585205287996">"జోడించండి"</string>
<string name="manage_users" msgid="1823875311934643849">"యూజర్లను మేనేజ్ చేయండి"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"ఈ నోటిఫికేషన్ స్ప్లిట్స్క్రీన్కు లాగడానికి సపోర్ట్ చేయదు."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"ఈ నోటిఫికేషన్ స్ప్లిట్ స్క్రీన్కు లాగడాన్ని సపోర్ట్ చేయదు"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi అందుబాటులో లేదు"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ముఖ్యమైన ఫైల్స్ మోడ్"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 9f909a9..d141402 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"เปิดใช้ USB"</string>
<string name="learn_more" msgid="4690632085667273811">"ดูข้อมูลเพิ่มเติม"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ภาพหน้าจอ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"ปิดใช้ฟีเจอร์ขยายเวลาปลดล็อกอยู่"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ส่งรูปภาพ"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"กำลังบันทึกภาพหน้าจอ..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"กำลังบันทึกภาพหน้าจอไปยังโปรไฟล์งาน…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{เพิ่มตัวควบคุม # ตัวแล้ว}other{เพิ่มตัวควบคุม # ตัวแล้ว}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"นำออกแล้ว"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"เพิ่ม <xliff:g id="APPNAME">%s</xliff:g> ไหม"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> สามารถเลือกตัวควบคุมและเนื้อหาที่จะปรากฏขึ้นที่นี่"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"นำการควบคุมสำหรับ <xliff:g id="APPNAME">%s</xliff:g> ออกไหม"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ตั้งเป็นรายการโปรดแล้ว"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ตั้งเป็นรายการโปรดแล้ว โดยอยู่ลำดับที่ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -899,7 +897,7 @@
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ควบคุมอุปกรณ์จากหน้าจอล็อกไหม"</string>
<string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"คุณควบคุมอุปกรณ์บางอย่างได้โดยไม่ต้องปลดล็อกโทรศัพท์หรือแท็บเล็ต แอปจัดการอุปกรณ์จะระบุอุปกรณ์ที่สามารถควบคุมด้วยวิธีนี้ได้"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ไม่เป็นไร"</string>
- <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"มี"</string>
+ <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ใช่"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ประกอบด้วยตัวอักษรหรือสัญลักษณ์"</string>
<string name="controls_pin_verify" msgid="3452778292918877662">"ยืนยัน <xliff:g id="DEVICE">%s</xliff:g>"</string>
<string name="controls_pin_wrong" msgid="6162694056042164211">"PIN ไม่ถูกต้อง"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"แก้ไข"</string>
<string name="add" msgid="81036585205287996">"เพิ่ม"</string>
<string name="manage_users" msgid="1823875311934643849">"จัดการผู้ใช้"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"การแจ้งเตือนนี้ไม่รองรับการลากเพื่อแบ่งหน้าจอ"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"การแจ้งเตือนนี้ไม่รองรับการลากเพื่อแยกหน้าจอ"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"ใช้ Wi‑Fi ไม่ได้"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"โหมดลำดับความสำคัญ"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 6326a97..732094f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"I-enable ang USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Matuto pa"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Na-disable ang Extend Unlock"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"nagpadala ng larawan"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Sine-save ang screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Sine-save ang screenshot sa profile sa trabaho…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Nagdagdag ng # kontrol.}one{Nagdagdag ng # kontrol.}other{Nagdagdag ng # na kontrol.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Inalis"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Idagdag ang <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"Mapipili ng <xliff:g id="APPNAME">%s</xliff:g> kung aling mga kontrol at content ang lalabas dito."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Alisin ang mga kontrol para sa <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ginawang paborito"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ginawang paborito, posisyon <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"i-edit"</string>
<string name="add" msgid="81036585205287996">"Magdagdag"</string>
<string name="manage_users" msgid="1823875311934643849">"Pamahalaan ang mga user"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Hindi sinusuportahan ng notification na ito ang pag-drag sa Splitscreen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Hindi sinusuportahan ng notification na ito ang pag-drag sa split screen"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Hindi available ang Wi‑Fi"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Priority mode"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5236912..3c3c079 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB\'yi etkinleştir"</string>
<string name="learn_more" msgid="4690632085667273811">"Daha fazla bilgi"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Ekran görüntüsü"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock devre dışı"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"bir resim gönderildi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ekran görüntüsü kaydediliyor..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ekran görüntüsü iş profiline kaydediliyor…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"düzenleyin"</string>
<string name="add" msgid="81036585205287996">"Ekle"</string>
<string name="manage_users" msgid="1823875311934643849">"Kullanıcıları yönet"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirim, bölünmüş ekrana sürüklenmeyi desteklemiyor."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Bu bildirim bölünmüş ekrana sürüklemeyi desteklemiyor"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Kablosuz kullanılamıyor"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Öncelik modu"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index b63b396..eecabf4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Увімкнути USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Докладніше"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Знімок екрана"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock вимкнено"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"надіслане зображення"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Збереження знімка екрана..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Зберігання знімка екрана в робочому профілі…"</string>
@@ -1067,7 +1066,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"змінити"</string>
<string name="add" msgid="81036585205287996">"Додати"</string>
<string name="manage_users" msgid="1823875311934643849">"Керувати користувачами"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Це сповіщення не підтримує режим розділеного екрана."</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Мережа Wi-Fi недоступна"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Режим пріоритету"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 7b98a2e..89e6930 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنٹرول کو شامل کیا گیا۔}other{# کنٹرولز کو شامل کیا گیا۔}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> کو شامل کریں؟"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> انتخاب کر سکتی ہے کہ یہاں کون سے کنٹرولز اور مواد دکھایا جائے۔"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> کے کنٹرولز کو ہٹا دیں؟"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"پسند کردہ، پوزیشن <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"ترمیم کریں"</string>
<string name="add" msgid="81036585205287996">"شامل کریں"</string>
<string name="manage_users" msgid="1823875311934643849">"صارفین کا نظم کریں"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"یہ اطلاع اسپلٹ اسکرین کو گھسیٹنے کو سپورٹ نہیں کرتا ہے۔"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"یہ اطلاع اسپلٹ اسکرین پر گھسیٹنے کو سپورٹ نہیں کرتی ہے"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi-Fi دستیاب نہیں ہے"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"ترجیحی وضع"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 15472f5..a701ae3 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -870,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> qoʻshilsinmi?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> bu yerda qaysi kontent va sozlamalar chiqishini tanlay oladi."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> qurilma boshqaruv panelidan olib tashlansinmi?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string>
@@ -1066,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"tahrir"</string>
<string name="add" msgid="81036585205287996">"Kiritish"</string>
<string name="manage_users" msgid="1823875311934643849">"Foydalanuvchilarni boshqarish"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Bu bildirishnoma ikkiga ajratilgan ekranda ishlamaydi."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi ishlamayapti"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imtiyozli rejim"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9e2d450..8f651b0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Bật USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Tìm hiểu thêm"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Chụp ảnh màn hình"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Đã tắt tính năng Luôn mở khoá"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"đã gửi hình ảnh"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Đang lưu ảnh chụp màn hình..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Đang lưu ảnh chụp màn hình vào hồ sơ công việc…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Thêm <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> có thể chọn các nút điều khiển và nội dung hiện ở đây."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Xoá chế độ cài đặt cho <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"sửa"</string>
<string name="add" msgid="81036585205287996">"Thêm"</string>
<string name="manage_users" msgid="1823875311934643849">"Quản lý người dùng"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Thông báo này không hỗ trợ thao tác kéo để Chia đôi màn hình."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Thông báo này không hỗ trợ thao tác kéo để chia đôi màn hình"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Không có Wi‑Fi"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Chế độ ưu tiên"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6b0e5d2..5532c29 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"启用 USB"</string>
<string name="learn_more" msgid="4690632085667273811">"了解详情"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"屏幕截图"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"已停用 Extend Unlock"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"发送了一张图片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在保存屏幕截图..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在将屏幕截图保存到工作资料…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"添加“<xliff:g id="APPNAME">%s</xliff:g>”?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"“<xliff:g id="APPNAME">%s</xliff:g>”可以选择在此处显示哪些控件和内容。"</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"移除<xliff:g id="APPNAME">%s</xliff:g>的控件?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,8 @@
<string name="clipboard_edit" msgid="4500155216174011640">"修改"</string>
<string name="add" msgid="81036585205287996">"添加"</string>
<string name="manage_users" msgid="1823875311934643849">"管理用户"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知不支持拖动到分屏中。"</string>
+ <!-- no translation found for drag_split_not_supported (7173481676120546121) -->
+ <skip />
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"WLAN 已关闭"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"优先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index d83891f..e6ece12 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"啟用 USB"</string>
<string name="learn_more" msgid="4690632085667273811">"瞭解詳情"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"螢幕截圖"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"「延長解鎖」功能已停用"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"已傳送圖片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在儲存螢幕擷取畫面..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在將螢幕截圖儲存至工作設定檔…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"編輯"</string>
<string name="add" msgid="81036585205287996">"新增"</string>
<string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"此通知無法拖曳到分割螢幕中。"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"此通知無法拖曳到分割螢幕中。"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index f50955e..7af44dc 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"啟用 USB 連接埠"</string>
<string name="learn_more" msgid="4690632085667273811">"瞭解詳情"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"螢幕截圖"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"「延長解鎖」功能已停用"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"傳送了一張圖片"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"正在儲存螢幕截圖…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"正在將螢幕截圖儲存到工作資料夾…"</string>
@@ -1067,7 +1066,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"編輯"</string>
<string name="add" msgid="81036585205287996">"新增"</string>
<string name="manage_users" msgid="1823875311934643849">"管理使用者"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"這項通知無法拖曳到分割畫面中。"</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"這項通知無法拖曳到分割畫面中。"</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi 已關閉"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"優先模式"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d3b1646..5a2af59 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Nika amandla i-USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Funda kabanzi"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Isithombe-skrini"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Ukwandisa Ukuvula kuvaliwe"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"uthumele isithombe"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Ilondoloz umfanekiso weskrini..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Ilondoloza isithombe-skrini kuphrofayela yomsebenzi…"</string>
@@ -871,8 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ulawulo olu-# olwengeziwe.}one{ukulawulwa okungu-# okwengeziwe.}other{ukulawulwa okungu-# okwengeziwe.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Engeza i-<xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
- <skip />
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"I-<xliff:g id="APPNAME">%s</xliff:g> ingakhetha ukuthi yiziphi izilawuli nokuqukethwe okuboniswa lapha."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Susa izilawuli ze-<xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kwenziwe intandokazi, isimo esiyi-<xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -1067,7 +1065,7 @@
<string name="clipboard_edit" msgid="4500155216174011640">"hlela"</string>
<string name="add" msgid="81036585205287996">"Faka"</string>
<string name="manage_users" msgid="1823875311934643849">"Phatha abasebenzisi"</string>
- <string name="drag_split_not_supported" msgid="4326847447699729722">"Lesi saziso asikusekeli ukuhudulela ku-Splitscreen."</string>
+ <string name="drag_split_not_supported" msgid="7173481676120546121">"Lesi saziso asikusekeli ukuhudulela ekuhlukaniseni isikrini."</string>
<string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"I-Wi-Fi ayitholakali"</string>
<string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Imodi ebalulekile"</string>
<string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 082f385..1602189 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -64,6 +64,10 @@
<!-- The number of rows in the QuickSettings -->
<integer name="quick_settings_max_rows">4</integer>
+ <!-- If the dp width of the available space is <= this value, potentially adjust the number
+ of media recommendation items-->
+ <integer name="default_qs_media_rec_width_dp">380</integer>
+
<!-- The number of columns that the top level tiles span in the QuickSettings -->
<!-- The default tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ff86c59..a52a2b7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1094,6 +1094,7 @@
<dimen name="qs_media_session_collapsed_guideline">144dp</dimen>
<!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
+ <dimen name="qs_media_rec_default_width">380dp</dimen>
<dimen name="qs_media_rec_icon_top_margin">16dp</dimen>
<dimen name="qs_media_rec_album_icon_size">16dp</dimen>
<dimen name="qs_media_rec_album_size">88dp</dimen>
@@ -1404,10 +1405,6 @@
-->
<dimen name="split_shade_scrim_transition_distance">300dp</dimen>
- <!-- Alpha in duration in ms for the auth ripple to become fully vislble. If set to 0,
- it is immediately visible. -->
- <integer name="auth_ripple_alpha_in_duration">100</integer>
-
<dimen name="people_space_widget_radius">28dp</dimen>
<dimen name="people_space_image_radius">20dp</dimen>
<dimen name="people_space_messages_count_radius">12dp</dimen>
@@ -1673,11 +1670,11 @@
.2
</item>
- <!-- The margins applied to the dream overlay container -->
- <dimen name="dream_overlay_container_margin_start">0dp</dimen>
- <dimen name="dream_overlay_container_margin_end">0dp</dimen>
- <dimen name="dream_overlay_container_margin_top">0dp</dimen>
- <dimen name="dream_overlay_container_margin_bottom">0dp</dimen>
+ <!-- The padding applied to the dream overlay container -->
+ <dimen name="dream_overlay_container_padding_start">0dp</dimen>
+ <dimen name="dream_overlay_container_padding_end">0dp</dimen>
+ <dimen name="dream_overlay_container_padding_top">0dp</dimen>
+ <dimen name="dream_overlay_container_padding_bottom">0dp</dimen>
<!-- The margin applied between complications -->
<dimen name="dream_overlay_complication_margin">0dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f2f0c59..1de3ddd 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -480,6 +480,11 @@
sCurrentUser = currentUser;
}
+ /**
+ * @deprecated This can potentially return unexpected values in a multi user scenario
+ * as this state is managed by another component. Consider using {@link UserTracker}.
+ */
+ @Deprecated
public synchronized static int getCurrentUser() {
return sCurrentUser;
}
@@ -3031,10 +3036,14 @@
.setUserId(userId)
.build());
} else {
- mLogger.v("startListeningForFingerprint - authenticate");
+ mLogger.v("startListeningForFingerprint");
mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,
- mFingerprintAuthenticationCallback, null /* handler */,
- FingerprintManager.SENSOR_ID_ANY, userId, 0 /* flags */);
+ mFingerprintAuthenticationCallback,
+ null /* handler */,
+ new FingerprintAuthenticateOptions.Builder()
+ .setUserId(userId)
+ .build()
+ );
}
setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt b/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt
new file mode 100644
index 0000000..2f03259
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ChooserPinMigration.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 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
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.Context.MODE_PRIVATE
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.os.Environment
+import android.os.storage.StorageManager
+import android.util.Log
+import androidx.core.util.Supplier
+import com.android.internal.R
+import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import java.io.File
+import javax.inject.Inject
+
+/**
+ * Performs a migration of pinned targets to the unbundled chooser if legacy data exists.
+ *
+ * Sends an explicit broadcast with the contents of the legacy pin preferences. The broadcast is
+ * protected by the RECEIVE_CHOOSER_PIN_MIGRATION permission. This class requires the
+ * ADD_CHOOSER_PINS permission in order to be able to send this broadcast.
+ */
+class ChooserPinMigration
+@Inject
+constructor(
+ private val context: Context,
+ private val featureFlags: FeatureFlags,
+ private val broadcastSender: BroadcastSender,
+ legacyPinPrefsFileSupplier: LegacyPinPrefsFileSupplier,
+) : CoreStartable {
+
+ private val legacyPinPrefsFile = legacyPinPrefsFileSupplier.get()
+ private val chooserComponent =
+ ComponentName.unflattenFromString(
+ context.resources.getString(R.string.config_chooserActivity)
+ )
+
+ override fun start() {
+ if (migrationIsRequired()) {
+ doMigration()
+ }
+ }
+
+ private fun migrationIsRequired(): Boolean {
+ return featureFlags.isEnabled(Flags.CHOOSER_MIGRATION_ENABLED) &&
+ legacyPinPrefsFile.exists() &&
+ chooserComponent?.packageName != null
+ }
+
+ private fun doMigration() {
+ Log.i(TAG, "Beginning migration")
+
+ val legacyPinPrefs = context.getSharedPreferences(legacyPinPrefsFile, MODE_PRIVATE)
+
+ if (legacyPinPrefs.all.isEmpty()) {
+ Log.i(TAG, "No data to migrate, deleting legacy file")
+ } else {
+ sendSharedPreferences(legacyPinPrefs)
+ Log.i(TAG, "Legacy data sent, deleting legacy preferences")
+
+ val legacyPinPrefsEditor = legacyPinPrefs.edit()
+ legacyPinPrefsEditor.clear()
+ if (!legacyPinPrefsEditor.commit()) {
+ Log.e(TAG, "Failed to delete legacy preferences")
+ return
+ }
+ }
+
+ if (!legacyPinPrefsFile.delete()) {
+ Log.e(TAG, "Legacy preferences deleted, but failed to delete legacy preferences file")
+ return
+ }
+
+ Log.i(TAG, "Legacy preference deletion complete")
+ }
+
+ private fun sendSharedPreferences(sharedPreferences: SharedPreferences) {
+ val bundle = Bundle()
+
+ sharedPreferences.all.entries.forEach { (key, value) ->
+ when (value) {
+ is Boolean -> bundle.putBoolean(key, value)
+ else -> Log.e(TAG, "Unsupported preference type for $key: ${value?.javaClass}")
+ }
+ }
+
+ sendBundle(bundle)
+ }
+
+ private fun sendBundle(bundle: Bundle) {
+ val intent =
+ Intent().apply {
+ `package` = chooserComponent?.packageName!!
+ action = BROADCAST_ACTION
+ putExtras(bundle)
+ }
+ broadcastSender.sendBroadcast(intent, BROADCAST_PERMISSION)
+ }
+
+ companion object {
+ private const val TAG = "PinnedShareTargetMigration"
+ private const val BROADCAST_ACTION = "android.intent.action.CHOOSER_PIN_MIGRATION"
+ private const val BROADCAST_PERMISSION = "android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
+
+ class LegacyPinPrefsFileSupplier @Inject constructor(private val context: Context) :
+ Supplier<File> {
+
+ override fun get(): File {
+ val packageDirectory =
+ Environment.getDataUserCePackageDirectory(
+ StorageManager.UUID_PRIVATE_INTERNAL,
+ context.userId,
+ context.packageName,
+ )
+ val sharedPrefsDirectory = File(packageDirectory, "shared_prefs")
+ return File(sharedPrefsDirectory, "chooser_pin_settings.xml")
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 873a695..64a9cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -16,6 +16,10 @@
package com.android.systemui;
+import static androidx.dynamicanimation.animation.DynamicAnimation.TRANSLATION_X;
+import static androidx.dynamicanimation.animation.DynamicAnimation.TRANSLATION_Y;
+import static androidx.dynamicanimation.animation.FloatPropertyCompat.createFloatPropertyCompat;
+
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import android.animation.Animator;
@@ -40,6 +44,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.internal.dynamicanimation.animation.SpringForce;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -47,14 +52,14 @@
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.wm.shell.animation.FlingAnimationUtils;
+import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.animation.PhysicsAnimator.SpringConfig;
import java.util.function.Consumer;
public class SwipeHelper implements Gefingerpoken {
static final String TAG = "com.android.systemui.SwipeHelper";
- private static final boolean DEBUG = false;
private static final boolean DEBUG_INVALIDATE = false;
- private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
private static final boolean CONSTRAIN_SWIPE = true;
private static final boolean FADE_OUT_DURING_SWIPE = true;
private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true;
@@ -66,7 +71,6 @@
private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
- private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
public static final float SWIPE_PROGRESS_FADE_END = 0.6f; // fraction of thumbnail width
// beyond which swipe progress->0
@@ -78,6 +82,9 @@
private float mMinSwipeProgress = 0f;
private float mMaxSwipeProgress = 1f;
+ private final SpringConfig mSnapBackSpringConfig =
+ new SpringConfig(SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+
private final FlingAnimationUtils mFlingAnimationUtils;
private float mPagingTouchSlop;
private final float mSlopMultiplier;
@@ -188,23 +195,27 @@
vt.getYVelocity();
}
- protected ObjectAnimator createTranslationAnimation(View v, float newPos) {
- ObjectAnimator anim = ObjectAnimator.ofFloat(v,
- mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
- return anim;
- }
-
- private float getPerpendicularVelocity(VelocityTracker vt) {
- return mSwipeDirection == X ? vt.getYVelocity() :
- vt.getXVelocity();
- }
-
- protected Animator getViewTranslationAnimator(View v, float target,
+ protected Animator getViewTranslationAnimator(View view, float target,
AnimatorUpdateListener listener) {
- ObjectAnimator anim = createTranslationAnimation(v, target);
+
+ cancelSnapbackAnimation(view);
+
+ if (view instanceof ExpandableNotificationRow) {
+ return ((ExpandableNotificationRow) view).getTranslateViewAnimator(target, listener);
+ }
+
+ return createTranslationAnimation(view, target, listener);
+ }
+
+ protected Animator createTranslationAnimation(View view, float newPos,
+ AnimatorUpdateListener listener) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(view,
+ mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
+
if (listener != null) {
anim.addUpdateListener(listener);
}
+
return anim;
}
@@ -327,6 +338,7 @@
mTouchedView = mCallback.getChildAtPosition(ev);
if (mTouchedView != null) {
+ cancelSnapbackAnimation(mTouchedView);
onDownUpdate(mTouchedView, ev);
mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mTouchedView);
mVelocityTracker.addMovement(ev);
@@ -526,47 +538,59 @@
}
/**
- * After snapChild() and related animation finished, this function will be called.
+ * Starts a snapback animation and cancels any previous translate animations on the given view.
+ *
+ * @param animView view to animate
+ * @param targetLeft the end position of the translation
+ * @param velocity the initial velocity of the animation
*/
- protected void onSnapChildWithAnimationFinished() {}
-
- public void snapChild(final View animView, final float targetLeft, float velocity) {
+ protected void snapChild(final View animView, final float targetLeft, float velocity) {
final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
- AnimatorUpdateListener updateListener = animation -> onTranslationUpdate(animView,
- (float) animation.getAnimatedValue(), canBeDismissed);
- Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
- if (anim == null) {
- onSnapChildWithAnimationFinished();
- return;
- }
- anim.addListener(new AnimatorListenerAdapter() {
- boolean wasCancelled = false;
+ cancelTranslateAnimation(animView);
- @Override
- public void onAnimationCancel(Animator animator) {
- wasCancelled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- mSnappingChild = false;
- if (!wasCancelled) {
- updateSwipeProgressFromOffset(animView, canBeDismissed);
- resetSwipeState();
- }
- onSnapChildWithAnimationFinished();
- }
+ PhysicsAnimator<? extends View> anim =
+ createSnapBackAnimation(animView, targetLeft, velocity);
+ anim.addUpdateListener((target, values) -> {
+ onTranslationUpdate(target, getTranslation(target), canBeDismissed);
});
- prepareSnapBackAnimation(animView, anim);
+ anim.addEndListener((t, p, wasFling, cancelled, finalValue, finalVelocity, allEnded) -> {
+ mSnappingChild = false;
+
+ if (!cancelled) {
+ updateSwipeProgressFromOffset(animView, canBeDismissed);
+ resetSwipeState();
+ }
+ onChildSnappedBack(animView, targetLeft);
+ });
mSnappingChild = true;
- float maxDistance = Math.abs(targetLeft - getTranslation(animView));
- mFlingAnimationUtils.apply(anim, getTranslation(animView), targetLeft, velocity,
- maxDistance);
anim.start();
- mCallback.onChildSnappedBack(animView, targetLeft);
}
+ private PhysicsAnimator<? extends View> createSnapBackAnimation(View target, float toPosition,
+ float startVelocity) {
+ if (target instanceof ExpandableNotificationRow) {
+ return PhysicsAnimator.getInstance((ExpandableNotificationRow) target).spring(
+ createFloatPropertyCompat(ExpandableNotificationRow.TRANSLATE_CONTENT),
+ toPosition,
+ startVelocity,
+ mSnapBackSpringConfig);
+ }
+ return PhysicsAnimator.getInstance(target).spring(
+ mSwipeDirection == X ? TRANSLATION_X : TRANSLATION_Y, toPosition, startVelocity,
+ mSnapBackSpringConfig);
+ }
+
+ private void cancelTranslateAnimation(View animView) {
+ if (animView instanceof ExpandableNotificationRow) {
+ ((ExpandableNotificationRow) animView).cancelTranslateAnimation();
+ }
+ cancelSnapbackAnimation(animView);
+ }
+
+ private void cancelSnapbackAnimation(View target) {
+ PhysicsAnimator.getInstance(target).cancel();
+ }
/**
* Called to update the content alpha while the view is swiped
@@ -576,17 +600,10 @@
}
/**
- * Give the swipe helper itself a chance to do something on snap back so NSSL doesn't have
- * to tell us what to do
+ * Called after {@link #snapChild(View, float, float)} and its related animation has finished.
*/
protected void onChildSnappedBack(View animView, float targetLeft) {
- }
-
- /**
- * Called to update the snap back animation.
- */
- protected void prepareSnapBackAnimation(View view, Animator anim) {
- // Do nothing
+ mCallback.onChildSnappedBack(animView, targetLeft);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 46e945b..868ffcf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -42,8 +42,8 @@
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.BiometricUnlockController
-import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER
import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -61,9 +61,7 @@
* The ripple uses the accent color of the current theme.
*/
@CentralSurfacesScope
-class AuthRippleController
-@Inject
-constructor(
+class AuthRippleController @Inject constructor(
private val centralSurfaces: CentralSurfaces,
private val sysuiContext: Context,
private val authController: AuthController,
@@ -73,18 +71,18 @@
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val commandRegistry: CommandRegistry,
private val notificationShadeWindowController: NotificationShadeWindowController,
+ private val bypassController: KeyguardBypassController,
private val biometricUnlockController: BiometricUnlockController,
private val udfpsControllerProvider: Provider<UdfpsController>,
private val statusBarStateController: StatusBarStateController,
private val featureFlags: FeatureFlags,
private val logger: KeyguardLogger,
- rippleView: AuthRippleView?
-) :
- ViewController<AuthRippleView>(rippleView),
- KeyguardStateController.Callback,
+ rippleView: AuthRippleView?
+) : ViewController<AuthRippleView>(rippleView), KeyguardStateController.Callback,
WakefulnessLifecycle.Observer {
- @VisibleForTesting internal var startLightRevealScrimOnKeyguardFadingAway = false
+ @VisibleForTesting
+ internal var startLightRevealScrimOnKeyguardFadingAway = false
var lightRevealScrimAnimator: ValueAnimator? = null
var fingerprintSensorLocation: Point? = null
private var faceSensorLocation: Point? = null
@@ -93,21 +91,6 @@
private var udfpsController: UdfpsController? = null
private var udfpsRadius: Float = -1f
- private val biometricModeListener = object : BiometricUnlockController.BiometricModeListener {
- override fun onModeChanged(mode: Int) {
- // isBiometricUnlock does not cover the scenario when biometrics unlocks
- // the device while the bouncer is showing.
- if (biometricUnlockController.isBiometricUnlock || mode == MODE_DISMISS_BOUNCER) {
- showUnlockRipple(biometricUnlockController.biometricType)
- }
- }
- }
-
- override fun onInit() {
- mView.setAlphaInDuration(sysuiContext.resources.getInteger(
- R.integer.auth_ripple_alpha_in_duration).toLong())
- }
-
@VisibleForTesting
public override fun onViewAttached() {
authController.addCallback(authControllerCallback)
@@ -119,7 +102,6 @@
keyguardStateController.addCallback(this)
wakefulnessLifecycle.addObserver(this)
commandRegistry.registerCommand("auth-ripple") { AuthRippleCommand() }
- biometricUnlockController.addBiometricModeListener(biometricModeListener)
}
@VisibleForTesting
@@ -131,7 +113,6 @@
keyguardStateController.removeCallback(this)
wakefulnessLifecycle.removeObserver(this)
commandRegistry.unregisterCommand("auth-ripple")
- biometricUnlockController.removeBiometricModeListener(biometricModeListener)
notificationShadeWindowController.setForcePluginOpen(false, this)
}
@@ -162,7 +143,10 @@
showUnlockedRipple()
}
} else if (biometricSourceType == BiometricSourceType.FACE) {
- faceSensorLocation?.let {
+ if (!bypassController.canBypass() && !authController.isUdfpsFingerDown) {
+ return
+ }
+ faceSensorLocation?.let {
mView.setSensorLocation(it)
circleReveal = CircleReveal(
it.x,
@@ -283,6 +267,7 @@
if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
mView.fadeDwellRipple()
}
+ showUnlockRipple(biometricSourceType)
}
override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 8409462..b007134 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -54,12 +54,11 @@
private var lockScreenColorVal = Color.WHITE
private val fadeDuration = 83L
private val retractDuration = 400L
- private var alphaInDuration: Long = 0
private val dwellShader = DwellRippleShader()
private val dwellPaint = Paint()
private val rippleShader = RippleShader()
private val ripplePaint = Paint()
- private var unlockedRippleAnimator: AnimatorSet? = null
+ private var unlockedRippleAnimator: Animator? = null
private var fadeDwellAnimator: Animator? = null
private var retractDwellAnimator: Animator? = null
private var dwellPulseOutAnimator: Animator? = null
@@ -85,12 +84,12 @@
}
init {
- rippleShader.color = 0xffffffff.toInt() // default color
rippleShader.rawProgress = 0f
rippleShader.pixelDensity = resources.displayMetrics.density
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
updateRippleFadeParams()
ripplePaint.shader = rippleShader
+ setLockScreenColor(0xffffffff.toInt()) // default color
dwellShader.color = 0xffffffff.toInt() // default color
dwellShader.progress = 0f
@@ -111,10 +110,6 @@
dwellRadius = sensorRadius * 1.5f
}
- fun setAlphaInDuration(duration: Long) {
- alphaInDuration = duration
- }
-
/**
* Animate dwell ripple inwards back to radius 0
*/
@@ -253,7 +248,6 @@
override fun onAnimationEnd(animation: Animator?) {
drawDwell = false
- resetRippleAlpha()
}
})
start()
@@ -277,22 +271,7 @@
}
}
- val alphaInAnimator = ValueAnimator.ofInt(0, 62).apply {
- duration = alphaInDuration
- addUpdateListener { animator ->
- rippleShader.color = ColorUtils.setAlphaComponent(
- rippleShader.color,
- animator.animatedValue as Int
- )
- invalidate()
- }
- }
-
- unlockedRippleAnimator = AnimatorSet().apply {
- playTogether(
- rippleAnimator,
- alphaInAnimator
- )
+ unlockedRippleAnimator = rippleAnimator.apply {
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
drawRipple = true
@@ -310,17 +289,12 @@
unlockedRippleAnimator?.start()
}
- fun resetRippleAlpha() {
- rippleShader.color = ColorUtils.setAlphaComponent(
- rippleShader.color,
- 255
- )
- }
-
fun setLockScreenColor(color: Int) {
lockScreenColorVal = color
- rippleShader.color = lockScreenColorVal
- resetRippleAlpha()
+ rippleShader.color = ColorUtils.setAlphaComponent(
+ lockScreenColorVal,
+ 62
+ )
}
fun updateDwellRippleColor(isDozing: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
deleted file mode 100644
index 079c0b3..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.graphics.PixelFormat
-import android.graphics.Point
-import android.graphics.Rect
-import android.hardware.biometrics.BiometricOverlayConstants
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
-import android.hardware.fingerprint.IUdfpsOverlay
-import android.os.Handler
-import android.provider.Settings
-import android.view.MotionEvent
-import android.view.WindowManager
-import android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY
-import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.settingslib.udfps.UdfpsOverlayParams
-import com.android.systemui.CoreStartable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.util.concurrency.DelayableExecutor
-import com.android.systemui.util.concurrency.Execution
-import java.util.Optional
-import java.util.concurrent.Executor
-import javax.inject.Inject
-import javax.inject.Provider
-import kotlin.math.cos
-import kotlin.math.pow
-import kotlin.math.sin
-
-private const val TAG = "UdfpsOverlay"
-
-const val SETTING_OVERLAY_DEBUG = "udfps_overlay_debug"
-
-// Number of sensor points needed inside ellipse for good overlap
-private const val NEEDED_POINTS = 2
-
-@SuppressLint("ClickableViewAccessibility")
-@SysUISingleton
-class UdfpsOverlay
-@Inject
-constructor(
- private val context: Context,
- private val execution: Execution,
- private val windowManager: WindowManager,
- private val fingerprintManager: FingerprintManager?,
- private val handler: Handler,
- private val biometricExecutor: Executor,
- private val alternateTouchProvider: Optional<Provider<AlternateUdfpsTouchProvider>>,
- @Main private val fgExecutor: DelayableExecutor,
- private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
- private val authController: AuthController,
- private val udfpsLogger: UdfpsLogger,
- private var featureFlags: FeatureFlags
-) : CoreStartable {
-
- /** The view, when [isShowing], or null. */
- var overlayView: UdfpsOverlayView? = null
- private set
-
- private var requestId: Long = 0
- private var onFingerDown = false
- val size = windowManager.maximumWindowMetrics.bounds
-
- val udfpsProps: MutableList<FingerprintSensorPropertiesInternal> = mutableListOf()
- var points: Array<Point> = emptyArray()
- var processedMotionEvent = false
- var isShowing = false
-
- private var params: UdfpsOverlayParams = UdfpsOverlayParams()
-
- private val coreLayoutParams =
- WindowManager.LayoutParams(
- WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
- 0 /* flags set in computeLayoutParams() */,
- PixelFormat.TRANSLUCENT
- )
- .apply {
- title = TAG
- fitInsetsTypes = 0
- gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
- layoutInDisplayCutoutMode =
- WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- flags = Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS
- privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
- // Avoid announcing window title.
- accessibilityTitle = " "
- inputFeatures = INPUT_FEATURE_SPY
- }
-
- fun onTouch(event: MotionEvent): Boolean {
- val view = overlayView!!
-
- return when (event.action) {
- MotionEvent.ACTION_DOWN,
- MotionEvent.ACTION_MOVE -> {
- onFingerDown = true
- if (!view.isDisplayConfigured && alternateTouchProvider.isPresent) {
- view.processMotionEvent(event)
-
- val goodOverlap =
- if (featureFlags.isEnabled(Flags.NEW_ELLIPSE_DETECTION)) {
- isGoodEllipseOverlap(event)
- } else {
- isGoodCentroidOverlap(event)
- }
-
- if (!processedMotionEvent && goodOverlap) {
- biometricExecutor.execute {
- alternateTouchProvider
- .map(Provider<AlternateUdfpsTouchProvider>::get)
- .get()
- .onPointerDown(
- requestId,
- event.rawX.toInt(),
- event.rawY.toInt(),
- event.touchMinor,
- event.touchMajor
- )
- }
- fgExecutor.execute {
- if (keyguardUpdateMonitor.isFingerprintDetectionRunning) {
- keyguardUpdateMonitor.onUdfpsPointerDown(requestId.toInt())
- }
-
- view.configureDisplay {
- biometricExecutor.execute {
- alternateTouchProvider
- .map(Provider<AlternateUdfpsTouchProvider>::get)
- .get()
- .onUiReady()
- }
- }
-
- processedMotionEvent = true
- }
- }
-
- view.invalidate()
- }
- true
- }
- MotionEvent.ACTION_UP,
- MotionEvent.ACTION_CANCEL -> {
- if (processedMotionEvent && alternateTouchProvider.isPresent) {
- biometricExecutor.execute {
- alternateTouchProvider
- .map(Provider<AlternateUdfpsTouchProvider>::get)
- .get()
- .onPointerUp(requestId)
- }
- fgExecutor.execute {
- if (keyguardUpdateMonitor.isFingerprintDetectionRunning) {
- keyguardUpdateMonitor.onUdfpsPointerUp(requestId.toInt())
- }
- }
-
- processedMotionEvent = false
- }
-
- if (view.isDisplayConfigured) {
- view.unconfigureDisplay()
- }
-
- view.invalidate()
- true
- }
- else -> false
- }
- }
-
- fun isGoodEllipseOverlap(event: MotionEvent): Boolean {
- return points.count { checkPoint(event, it) } >= NEEDED_POINTS
- }
-
- fun isGoodCentroidOverlap(event: MotionEvent): Boolean {
- return params.sensorBounds.contains(event.rawX.toInt(), event.rawY.toInt())
- }
-
- fun checkPoint(event: MotionEvent, point: Point): Boolean {
- // Calculate if sensor point is within ellipse
- // Formula: ((cos(o)(xE - xS) + sin(o)(yE - yS))^2 / a^2) + ((sin(o)(xE - xS) + cos(o)(yE -
- // yS))^2 / b^2) <= 1
- val a: Float = cos(event.orientation) * (point.x - event.rawX)
- val b: Float = sin(event.orientation) * (point.y - event.rawY)
- val c: Float = sin(event.orientation) * (point.x - event.rawX)
- val d: Float = cos(event.orientation) * (point.y - event.rawY)
- val result =
- (a + b).pow(2) / (event.touchMinor / 2).pow(2) +
- (c - d).pow(2) / (event.touchMajor / 2).pow(2)
-
- return result <= 1
- }
-
- fun show(requestId: Long) {
- if (!featureFlags.isEnabled(Flags.NEW_UDFPS_OVERLAY)) {
- return
- }
-
- this.requestId = requestId
- fgExecutor.execute {
- if (overlayView == null && alternateTouchProvider.isPresent) {
- UdfpsOverlayView(context, null).let {
- it.overlayParams = params
- it.setUdfpsDisplayMode(
- UdfpsDisplayMode(context, execution, authController, udfpsLogger)
- )
- it.setOnTouchListener { _, event -> onTouch(event) }
- it.sensorPoints = points
- it.debugOverlay =
- Settings.Global.getInt(
- context.contentResolver,
- SETTING_OVERLAY_DEBUG,
- 0 /* def */
- ) != 0
- overlayView = it
- }
- windowManager.addView(overlayView, coreLayoutParams)
- isShowing = true
- }
- }
- }
-
- fun hide() {
- if (!featureFlags.isEnabled(Flags.NEW_UDFPS_OVERLAY)) {
- return
- }
-
- fgExecutor.execute {
- if (overlayView != null && isShowing && alternateTouchProvider.isPresent) {
- if (processedMotionEvent) {
- biometricExecutor.execute {
- alternateTouchProvider
- .map(Provider<AlternateUdfpsTouchProvider>::get)
- .get()
- .onPointerUp(requestId)
- }
- fgExecutor.execute {
- if (keyguardUpdateMonitor.isFingerprintDetectionRunning) {
- keyguardUpdateMonitor.onUdfpsPointerUp(requestId.toInt())
- }
- }
- }
-
- if (overlayView!!.isDisplayConfigured) {
- overlayView!!.unconfigureDisplay()
- }
-
- overlayView?.apply {
- windowManager.removeView(this)
- setOnTouchListener(null)
- }
-
- isShowing = false
- overlayView = null
- processedMotionEvent = false
- }
- }
- }
-
- @Override
- override fun start() {
- fingerprintManager?.addAuthenticatorsRegisteredCallback(
- object : IFingerprintAuthenticatorsRegisteredCallback.Stub() {
- override fun onAllAuthenticatorsRegistered(
- sensors: List<FingerprintSensorPropertiesInternal>
- ) {
- handler.post { handleAllFingerprintAuthenticatorsRegistered(sensors) }
- }
- }
- )
-
- fingerprintManager?.setUdfpsOverlay(
- object : IUdfpsOverlay.Stub() {
- override fun show(
- requestId: Long,
- sensorId: Int,
- @BiometricOverlayConstants.ShowReason reason: Int
- ) = show(requestId)
-
- override fun hide(sensorId: Int) = hide()
- }
- )
- }
-
- private fun handleAllFingerprintAuthenticatorsRegistered(
- sensors: List<FingerprintSensorPropertiesInternal>
- ) {
- for (props in sensors) {
- if (props.isAnyUdfpsType) {
- udfpsProps.add(props)
- }
- }
-
- // Setup param size
- if (udfpsProps.isNotEmpty()) {
- params =
- UdfpsOverlayParams(
- sensorBounds = udfpsProps[0].location.rect,
- overlayBounds = Rect(0, size.height() / 2, size.width(), size.height()),
- naturalDisplayWidth = size.width(),
- naturalDisplayHeight = size.height(),
- scaleFactor = 1f
- )
-
- val sensorX = params.sensorBounds.centerX()
- val sensorY = params.sensorBounds.centerY()
- val cornerOffset: Int = params.sensorBounds.width() / 4
- val sideOffset: Int = params.sensorBounds.width() / 3
-
- points =
- arrayOf(
- Point(sensorX - cornerOffset, sensorY - cornerOffset),
- Point(sensorX, sensorY - sideOffset),
- Point(sensorX + cornerOffset, sensorY - cornerOffset),
- Point(sensorX - sideOffset, sensorY),
- Point(sensorX, sensorY),
- Point(sensorX + sideOffset, sensorY),
- Point(sensorX - cornerOffset, sensorY + cornerOffset),
- Point(sensorX, sensorY + sideOffset),
- Point(sensorX + cornerOffset, sensorY + cornerOffset)
- )
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
deleted file mode 100644
index 28ca41d..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Color
-import android.graphics.Paint
-import android.graphics.Point
-import android.graphics.RectF
-import android.util.AttributeSet
-import android.view.MotionEvent
-import android.widget.FrameLayout
-import com.android.settingslib.udfps.UdfpsOverlayParams
-
-private const val TAG = "UdfpsOverlayView"
-private const val POINT_SIZE = 10f
-
-class UdfpsOverlayView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
- var overlayParams = UdfpsOverlayParams()
- private var mUdfpsDisplayMode: UdfpsDisplayMode? = null
-
- var debugOverlay = false
-
- var overlayPaint = Paint()
- var sensorPaint = Paint()
- var touchPaint = Paint()
- var pointPaint = Paint()
- val centerPaint = Paint()
-
- var oval = RectF()
-
- /** True after the call to [configureDisplay] and before the call to [unconfigureDisplay]. */
- var isDisplayConfigured: Boolean = false
- private set
-
- var touchX: Float = 0f
- var touchY: Float = 0f
- var touchMinor: Float = 0f
- var touchMajor: Float = 0f
- var touchOrientation: Double = 0.0
-
- var sensorPoints: Array<Point>? = null
-
- init {
- this.setWillNotDraw(false)
- }
-
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
-
- overlayPaint.color = Color.argb(100, 255, 0, 0)
- overlayPaint.style = Paint.Style.FILL
-
- touchPaint.color = Color.argb(200, 255, 255, 255)
- touchPaint.style = Paint.Style.FILL
-
- sensorPaint.color = Color.argb(150, 134, 204, 255)
- sensorPaint.style = Paint.Style.FILL
-
- pointPaint.color = Color.WHITE
- pointPaint.style = Paint.Style.FILL
- }
-
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
-
- if (debugOverlay) {
- // Draw overlay and sensor bounds
- canvas.drawRect(overlayParams.overlayBounds, overlayPaint)
- canvas.drawRect(overlayParams.sensorBounds, sensorPaint)
- }
-
- // Draw sensor circle
- canvas.drawCircle(
- overlayParams.sensorBounds.exactCenterX(),
- overlayParams.sensorBounds.exactCenterY(),
- overlayParams.sensorBounds.width().toFloat() / 2,
- centerPaint
- )
-
- if (debugOverlay) {
- // Draw Points
- sensorPoints?.forEach {
- canvas.drawCircle(it.x.toFloat(), it.y.toFloat(), POINT_SIZE, pointPaint)
- }
-
- // Draw touch oval
- canvas.save()
- canvas.rotate(Math.toDegrees(touchOrientation).toFloat(), touchX, touchY)
-
- oval.setEmpty()
- oval.set(
- touchX - touchMinor / 2,
- touchY + touchMajor / 2,
- touchX + touchMinor / 2,
- touchY - touchMajor / 2
- )
-
- canvas.drawOval(oval, touchPaint)
-
- // Draw center point
- canvas.drawCircle(touchX, touchY, POINT_SIZE, centerPaint)
- canvas.restore()
- }
- }
-
- fun setUdfpsDisplayMode(udfpsDisplayMode: UdfpsDisplayMode?) {
- mUdfpsDisplayMode = udfpsDisplayMode
- }
-
- fun configureDisplay(onDisplayConfigured: Runnable) {
- isDisplayConfigured = true
- mUdfpsDisplayMode?.enable(onDisplayConfigured)
- }
-
- fun unconfigureDisplay() {
- isDisplayConfigured = false
- mUdfpsDisplayMode?.disable(null /* onDisabled */)
- }
-
- fun processMotionEvent(event: MotionEvent) {
- touchX = event.rawX
- touchY = event.rawY
- touchMinor = event.touchMinor
- touchMajor = event.touchMajor
- touchOrientation = event.orientation.toDouble()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
index fca4cf9..e3dbcb5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
@@ -50,8 +50,7 @@
*/
@SysUISingleton
class UdfpsShell @Inject constructor(
- commandRegistry: CommandRegistry,
- private val udfpsOverlay: UdfpsOverlay
+ commandRegistry: CommandRegistry
) : Command {
/**
@@ -69,10 +68,6 @@
override fun execute(pw: PrintWriter, args: List<String>) {
if (args.size == 1 && args[0] == "hide") {
hideOverlay()
- } else if (args.size == 2 && args[0] == "udfpsOverlay" && args[1] == "show") {
- showUdfpsOverlay()
- } else if (args.size == 2 && args[0] == "udfpsOverlay" && args[1] == "hide") {
- hideUdfpsOverlay()
} else if (args.size == 2 && args[0] == "show") {
showOverlay(getEnrollmentReason(args[1]))
} else if (args.size == 1 && args[0] == "onUiReady") {
@@ -131,16 +126,6 @@
)
}
- private fun showUdfpsOverlay() {
- Log.v(TAG, "showUdfpsOverlay")
- udfpsOverlay.show(REQUEST_ID)
- }
-
- private fun hideUdfpsOverlay() {
- Log.v(TAG, "hideUdfpsOverlay")
- udfpsOverlay.hide()
- }
-
private fun hideOverlay() {
udfpsOverlayController?.hideUdfpsOverlay(SENSOR_ID)
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
index 3b53eff..000213f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics.domain.interactor
+import android.hardware.biometrics.AuthenticateOptions
import android.hardware.biometrics.IBiometricContextListener
import android.util.Log
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -23,7 +24,8 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.WakefulnessLifecycle
-import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
@@ -39,6 +41,7 @@
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
@@ -49,8 +52,8 @@
*/
interface LogContextInteractor {
- /** If the device is dozing. */
- val isDozing: Flow<Boolean>
+ /** If the device is showing aod. */
+ val isAod: Flow<Boolean>
/** If the device is currently awake with the screen on. */
val isAwake: Flow<Boolean>
@@ -58,6 +61,9 @@
/** Current device fold state, defined as [IBiometricContextListener.FoldState]. */
val foldState: Flow<Int>
+ /** Current display state, defined as [AuthenticateOptions.DisplayState] */
+ val displayState: Flow<Int>
+
/**
* Add a permanent context listener.
*
@@ -72,46 +78,41 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- private val statusBarStateController: StatusBarStateController,
- private val wakefulnessLifecycle: WakefulnessLifecycle,
private val foldProvider: FoldStateProvider,
+ keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : LogContextInteractor {
init {
foldProvider.start()
}
- override val isDozing =
- conflatedCallbackFlow {
- val callback =
- object : StatusBarStateController.StateListener {
- override fun onDozingChanged(isDozing: Boolean) {
- trySendWithFailureLogging(isDozing, TAG)
- }
- }
-
- statusBarStateController.addCallback(callback)
- trySendWithFailureLogging(statusBarStateController.isDozing, TAG)
- awaitClose { statusBarStateController.removeCallback(callback) }
+ override val displayState =
+ keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
+ when (it.to) {
+ KeyguardState.LOCKSCREEN,
+ KeyguardState.OCCLUDED,
+ KeyguardState.ALTERNATE_BOUNCER,
+ KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+ KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
+ KeyguardState.OFF,
+ KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
+ KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
+ else -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
}
- .distinctUntilChanged()
+ }
+
+ override val isAod =
+ displayState.map { it == AuthenticateOptions.DISPLAY_STATE_AOD }.distinctUntilChanged()
override val isAwake =
- conflatedCallbackFlow {
- val callback =
- object : WakefulnessLifecycle.Observer {
- override fun onFinishedWakingUp() {
- trySendWithFailureLogging(true, TAG)
- }
-
- override fun onStartedGoingToSleep() {
- trySendWithFailureLogging(false, TAG)
- }
- }
-
- wakefulnessLifecycle.addObserver(callback)
- trySendWithFailureLogging(wakefulnessLifecycle.isAwake, TAG)
- awaitClose { wakefulnessLifecycle.removeObserver(callback) }
+ displayState
+ .map {
+ when (it) {
+ AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN,
+ AuthenticateOptions.DISPLAY_STATE_SCREENSAVER,
+ AuthenticateOptions.DISPLAY_STATE_UNKNOWN -> true
+ else -> false
+ }
}
.distinctUntilChanged()
@@ -146,8 +147,8 @@
override fun addBiometricContextListener(listener: IBiometricContextListener): Job {
return applicationScope.launch {
- combine(isDozing, isAwake) { doze, awake -> doze to awake }
- .onEach { (doze, awake) -> listener.onDozeChanged(doze, awake) }
+ combine(isAod, isAwake) { doze, awake -> doze to awake }
+ .onEach { (aod, awake) -> listener.onDozeChanged(aod, awake) }
.catch { t -> Log.w(TAG, "failed to notify new doze state", t) }
.launchIn(this)
@@ -156,6 +157,12 @@
.catch { t -> Log.w(TAG, "failed to notify new fold state", t) }
.launchIn(this)
+ displayState
+ .distinctUntilChanged()
+ .onEach { state -> listener.onDisplayStateChanged(state) }
+ .catch { t -> Log.w(TAG, "failed to notify new display state", t) }
+ .launchIn(this)
+
listener.asBinder().linkToDeath({ cancel() }, 0)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
index 653c12e..25b1e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
@@ -16,8 +16,15 @@
package com.android.systemui.bluetooth;
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.bluetooth.BluetoothLeBroadcast;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -28,11 +35,18 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.media.MediaOutputConstants;
import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.media.controls.util.MediaDataUtils;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.statusbar.phone.SystemUIDialog;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
/**
* Dialog for showing le audio broadcasting dialog.
*/
@@ -40,17 +54,91 @@
private static final String TAG = "BroadcastDialog";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int HANDLE_BROADCAST_FAILED_DELAY = 3000;
+
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
private Context mContext;
private UiEventLogger mUiEventLogger;
@VisibleForTesting
protected View mDialogView;
private MediaOutputDialogFactory mMediaOutputDialogFactory;
+ private LocalBluetoothManager mLocalBluetoothManager;
+ private BroadcastSender mBroadcastSender;
private String mCurrentBroadcastApp;
private String mOutputPackageName;
+ private Executor mExecutor;
+ private boolean mShouldLaunchLeBroadcastDialog;
+ private Button mSwitchBroadcast;
+
+ private final BluetoothLeBroadcast.Callback mBroadcastCallback =
+ new BluetoothLeBroadcast.Callback() {
+ @Override
+ public void onBroadcastStarted(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStarted(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> handleLeBroadcastStarted());
+ }
+
+ @Override
+ public void onBroadcastStartFailed(int reason) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
+ }
+ mMainThreadHandler.postDelayed(() -> handleLeBroadcastStartFailed(),
+ HANDLE_BROADCAST_FAILED_DELAY);
+ }
+
+ @Override
+ public void onBroadcastMetadataChanged(int broadcastId,
+ @NonNull BluetoothLeBroadcastMetadata metadata) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId
+ + ", metadata = " + metadata);
+ }
+ mMainThreadHandler.post(() -> handleLeBroadcastMetadataChanged());
+ }
+
+ @Override
+ public void onBroadcastStopped(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStopped(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> handleLeBroadcastStopped());
+ }
+
+ @Override
+ public void onBroadcastStopFailed(int reason) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
+ }
+ mMainThreadHandler.postDelayed(() -> handleLeBroadcastStopFailed(),
+ HANDLE_BROADCAST_FAILED_DELAY);
+ }
+
+ @Override
+ public void onBroadcastUpdated(int reason, int broadcastId) {
+ }
+
+ @Override
+ public void onBroadcastUpdateFailed(int reason, int broadcastId) {
+ }
+
+ @Override
+ public void onPlaybackStarted(int reason, int broadcastId) {
+ }
+
+ @Override
+ public void onPlaybackStopped(int reason, int broadcastId) {
+ }
+ };
public BroadcastDialog(Context context, MediaOutputDialogFactory mediaOutputDialogFactory,
- String currentBroadcastApp, String outputPkgName, UiEventLogger uiEventLogger) {
+ LocalBluetoothManager localBluetoothManager, String currentBroadcastApp,
+ String outputPkgName, UiEventLogger uiEventLogger, BroadcastSender broadcastSender) {
super(context);
if (DEBUG) {
Log.d(TAG, "Init BroadcastDialog");
@@ -58,9 +146,18 @@
mContext = getContext();
mMediaOutputDialogFactory = mediaOutputDialogFactory;
+ mLocalBluetoothManager = localBluetoothManager;
mCurrentBroadcastApp = currentBroadcastApp;
mOutputPackageName = outputPkgName;
mUiEventLogger = uiEventLogger;
+ mExecutor = Executors.newSingleThreadExecutor();
+ mBroadcastSender = broadcastSender;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ registerBroadcastCallBack(mExecutor, mBroadcastCallback);
}
@Override
@@ -84,11 +181,12 @@
subTitle.setText(mContext.getString(
R.string.bt_le_audio_broadcast_dialog_sub_title, switchBroadcastApp));
- Button switchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
+ mSwitchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
Button changeOutput = mDialogView.requireViewById(R.id.change_output);
Button cancelBtn = mDialogView.requireViewById(R.id.cancel);
- switchBroadcast.setText(mContext.getString(
- R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp));
+ mSwitchBroadcast.setText(mContext.getString(
+ R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp), null);
+ mSwitchBroadcast.setOnClickListener((view) -> startSwitchBroadcast());
changeOutput.setOnClickListener((view) -> {
mMediaOutputDialogFactory.create(mOutputPackageName, true, null);
dismiss();
@@ -102,6 +200,79 @@
}
@Override
+ public void onStop() {
+ super.onStop();
+ unregisterBroadcastCallBack(mBroadcastCallback);
+ }
+
+ void refreshSwitchBroadcastButton() {
+ String switchBroadcastApp = MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
+ mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name));
+ mSwitchBroadcast.setText(mContext.getString(
+ R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp), null);
+ mSwitchBroadcast.setEnabled(true);
+ }
+
+ private void startSwitchBroadcast() {
+ if (DEBUG) {
+ Log.d(TAG, "startSwitchBroadcast");
+ }
+ mSwitchBroadcast.setText(R.string.media_output_broadcast_starting);
+ mSwitchBroadcast.setEnabled(false);
+ //Stop the current Broadcast
+ if (!stopBluetoothLeBroadcast()) {
+ handleLeBroadcastStopFailed();
+ return;
+ }
+ }
+
+ private void registerBroadcastCallBack(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BluetoothLeBroadcast.Callback callback) {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return;
+ }
+ broadcast.registerServiceCallBack(executor, callback);
+ }
+
+ private void unregisterBroadcastCallBack(@NonNull BluetoothLeBroadcast.Callback callback) {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return;
+ }
+ broadcast.unregisterServiceCallBack(callback);
+ }
+
+ boolean startBluetoothLeBroadcast() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return false;
+ }
+ String switchBroadcastApp = MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
+ mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name));
+ broadcast.startBroadcast(switchBroadcastApp, /*language*/ null);
+ return true;
+ }
+
+ boolean stopBluetoothLeBroadcast() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return false;
+ }
+ broadcast.stopLatestBroadcast();
+ return true;
+ }
+
+ @Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus && isShowing()) {
@@ -125,4 +296,45 @@
}
}
+ void handleLeBroadcastStarted() {
+ // Waiting for the onBroadcastMetadataChanged. The UI launchs the broadcast dialog when
+ // the metadata is ready.
+ mShouldLaunchLeBroadcastDialog = true;
+ }
+
+ private void handleLeBroadcastStartFailed() {
+ mSwitchBroadcast.setText(R.string.media_output_broadcast_start_failed);
+ mSwitchBroadcast.setEnabled(false);
+ refreshSwitchBroadcastButton();
+ }
+
+ void handleLeBroadcastMetadataChanged() {
+ if (mShouldLaunchLeBroadcastDialog) {
+ startLeBroadcastDialog();
+ mShouldLaunchLeBroadcastDialog = false;
+ }
+ }
+
+ @VisibleForTesting
+ void handleLeBroadcastStopped() {
+ mShouldLaunchLeBroadcastDialog = false;
+ if (!startBluetoothLeBroadcast()) {
+ handleLeBroadcastStartFailed();
+ return;
+ }
+ }
+
+ private void handleLeBroadcastStopFailed() {
+ mSwitchBroadcast.setText(R.string.media_output_broadcast_start_failed);
+ mSwitchBroadcast.setEnabled(false);
+ refreshSwitchBroadcastButton();
+ }
+
+ private void startLeBroadcastDialog() {
+ mBroadcastSender.sendBroadcast(new Intent()
+ .setPackage(mContext.getPackageName())
+ .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG)
+ .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, mOutputPackageName));
+ dismiss();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
index 1b699e8..17bf1a7 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
@@ -16,11 +16,14 @@
package com.android.systemui.bluetooth;
+import android.annotation.Nullable;
import android.content.Context;
import android.view.View;
import com.android.internal.logging.UiEventLogger;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -36,15 +39,21 @@
private UiEventLogger mUiEventLogger;
private DialogLaunchAnimator mDialogLaunchAnimator;
private MediaOutputDialogFactory mMediaOutputDialogFactory;
+ private final LocalBluetoothManager mLocalBluetoothManager;
+ private BroadcastSender mBroadcastSender;
@Inject
public BroadcastDialogController(Context context, UiEventLogger uiEventLogger,
DialogLaunchAnimator dialogLaunchAnimator,
- MediaOutputDialogFactory mediaOutputDialogFactory) {
+ MediaOutputDialogFactory mediaOutputDialogFactory,
+ @Nullable LocalBluetoothManager localBluetoothManager,
+ BroadcastSender broadcastSender) {
mContext = context;
mUiEventLogger = uiEventLogger;
mDialogLaunchAnimator = dialogLaunchAnimator;
mMediaOutputDialogFactory = mediaOutputDialogFactory;
+ mLocalBluetoothManager = localBluetoothManager;
+ mBroadcastSender = broadcastSender;
}
/** Creates a [BroadcastDialog] for the user to switch broadcast or change the output device
@@ -55,7 +64,8 @@
public void createBroadcastDialog(String currentBroadcastAppName, String outputPkgName,
boolean aboveStatusBar, View view) {
BroadcastDialog broadcastDialog = new BroadcastDialog(mContext, mMediaOutputDialogFactory,
- currentBroadcastAppName, outputPkgName, mUiEventLogger);
+ mLocalBluetoothManager, currentBroadcastAppName, outputPkgName, mUiEventLogger,
+ mBroadcastSender);
if (view != null) {
mDialogLaunchAnimator.showFromView(broadcastDialog, view);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
index 0ed7d27..e9daa46 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardToast.java
@@ -41,6 +41,7 @@
}
mCopiedToast = Toast.makeText(mContext,
R.string.clipboard_overlay_text_copied, Toast.LENGTH_SHORT);
+ mCopiedToast.addCallback(this);
mCopiedToast.show();
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index 224eb1c..c964b96 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -47,7 +47,8 @@
* destroyed on SCREEN_OFF events, due to issues with occluded activities over lockscreen as well as
* user expectations for the activity to not continue running.
*/
-class ControlsActivity @Inject constructor(
+// Open for testing
+open class ControlsActivity @Inject constructor(
private val uiController: ControlsUiController,
private val broadcastDispatcher: BroadcastDispatcher,
private val dreamManager: IDreamManager,
@@ -98,8 +99,11 @@
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
- if (lastConfiguration.diff(newConfig) and ActivityInfo.CONFIG_ORIENTATION != 0 ) {
- uiController.onOrientationChange()
+ val interestingFlags = ActivityInfo.CONFIG_ORIENTATION or
+ ActivityInfo.CONFIG_SCREEN_SIZE or
+ ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
+ if (lastConfiguration.diff(newConfig) and interestingFlags != 0 ) {
+ uiController.onSizeChange()
}
lastConfiguration = newConfig
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index 3ecf423..0cc4683 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -65,7 +65,7 @@
*/
fun getPreferredSelectedItem(structures: List<StructureInfo>): SelectedItem
- fun onOrientationChange()
+ fun onSizeChange()
}
sealed class SelectedItem {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 868e527..09ba373 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -809,7 +809,7 @@
}
}
- override fun onOrientationChange() {
+ override fun onSizeChange() {
selectionItem?.let {
when (selectedItem) {
is SelectedItem.StructureItem -> createListView(it)
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index b86d419..df236e7 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.dagger
import com.android.keyguard.KeyguardBiometricLockoutLogger
+import com.android.systemui.ChooserPinMigration
import com.android.systemui.ChooserSelector
import com.android.systemui.CoreStartable
import com.android.systemui.LatencyTester
@@ -25,7 +26,6 @@
import com.android.systemui.accessibility.SystemActions
import com.android.systemui.accessibility.WindowMagnification
import com.android.systemui.biometrics.AuthController
-import com.android.systemui.biometrics.UdfpsOverlay
import com.android.systemui.clipboardoverlay.ClipboardListener
import com.android.systemui.controls.dagger.StartControlsStartableModule
import com.android.systemui.dagger.qualifiers.PerUser
@@ -76,6 +76,13 @@
@ClassKey(AuthController::class)
abstract fun bindAuthController(service: AuthController): CoreStartable
+ /** Inject into ChooserPinMigration. */
+ @Binds
+ @IntoMap
+ @ClassKey(ChooserPinMigration::class)
+ @PerUser
+ abstract fun bindChooserPinMigration(sysui: ChooserPinMigration): CoreStartable
+
/** Inject into ChooserCoreStartable. */
@Binds
@IntoMap
@@ -229,12 +236,6 @@
@ClassKey(KeyguardLiftController::class)
abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable
- /** Inject into UdfpsOverlay. */
- @Binds
- @IntoMap
- @ClassKey(UdfpsOverlay::class)
- abstract fun bindUdfpsOverlay(sysui: UdfpsOverlay): CoreStartable
-
/** Inject into MediaTttSenderCoordinator. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index fc3263f..f0aefb5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -398,7 +398,8 @@
}
if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING
|| mState == State.DOZE_AOD || mState == State.DOZE
- || mState == State.DOZE_AOD_DOCKED) && requestedState == State.DOZE_PULSE_DONE) {
+ || mState == State.DOZE_AOD_DOCKED || mState == State.DOZE_SUSPEND_TRIGGERS)
+ && requestedState == State.DOZE_PULSE_DONE) {
Log.i(TAG, "Dropping pulse done because current state is already done: " + mState);
return mState;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index b7f6a70..7790986 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -27,6 +27,8 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.policy.CallbackController;
import java.util.ArrayList;
@@ -104,12 +106,24 @@
private final Collection<Complication> mComplications = new HashSet();
+ private final FeatureFlags mFeatureFlags;
+
+ private final int mSupportedTypes;
+
@VisibleForTesting
@Inject
public DreamOverlayStateController(@Main Executor executor,
- @Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled) {
+ @Named(DREAM_OVERLAY_ENABLED) boolean overlayEnabled,
+ FeatureFlags featureFlags) {
mExecutor = executor;
mOverlayEnabled = overlayEnabled;
+ mFeatureFlags = featureFlags;
+ if (mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)) {
+ mSupportedTypes = Complication.COMPLICATION_TYPE_NONE
+ | Complication.COMPLICATION_TYPE_HOME_CONTROLS;
+ } else {
+ mSupportedTypes = Complication.COMPLICATION_TYPE_NONE;
+ }
if (DEBUG) {
Log.d(TAG, "Dream overlay enabled:" + mOverlayEnabled);
}
@@ -181,7 +195,7 @@
if (mShouldShowComplications) {
return (requiredTypes & getAvailableComplicationTypes()) == requiredTypes;
}
- return requiredTypes == Complication.COMPLICATION_TYPE_NONE;
+ return (requiredTypes & mSupportedTypes) == requiredTypes;
})
.collect(Collectors.toCollection(HashSet::new))
: mComplications);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index a7b3bbc..2ea7bce 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -25,7 +25,6 @@
import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.graphics.Region;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.InputEvent;
@@ -89,8 +88,6 @@
private final FlingAnimationUtils mFlingAnimationUtils;
private final FlingAnimationUtils mFlingAnimationUtilsClosing;
- private final DisplayMetrics mDisplayMetrics;
-
private Boolean mCapture;
private Boolean mExpanded;
@@ -161,7 +158,7 @@
// (0).
final float dragDownAmount = e2.getY() - e1.getY();
final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
- / mCentralSurfaces.get().getDisplayHeight();
+ / mTouchSession.getBounds().height();
setPanelExpansion(mBouncerInitiallyShowing
? screenTravelPercentage : 1 - screenTravelPercentage, dragDownAmount);
return true;
@@ -202,7 +199,6 @@
@Inject
public BouncerSwipeTouchHandler(
- DisplayMetrics displayMetrics,
ScrimManager scrimManager,
Optional<CentralSurfaces> centralSurfaces,
NotificationShadeWindowController notificationShadeWindowController,
@@ -214,7 +210,6 @@
FlingAnimationUtils flingAnimationUtilsClosing,
@Named(SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage,
UiEventLogger uiEventLogger) {
- mDisplayMetrics = displayMetrics;
mCentralSurfaces = centralSurfaces;
mScrimManager = scrimManager;
mNotificationShadeWindowController = notificationShadeWindowController;
@@ -227,19 +222,20 @@
}
@Override
- public void getTouchInitiationRegion(Region region) {
+ public void getTouchInitiationRegion(Rect bounds, Region region) {
+ final int width = bounds.width();
+ final int height = bounds.height();
+
if (mCentralSurfaces.map(CentralSurfaces::isBouncerShowing).orElse(false)) {
- region.op(new Rect(0, 0, mDisplayMetrics.widthPixels,
+ region.op(new Rect(0, 0, width,
Math.round(
- mDisplayMetrics.heightPixels * mBouncerZoneScreenPercentage)),
+ height * mBouncerZoneScreenPercentage)),
Region.Op.UNION);
} else {
region.op(new Rect(0,
- Math.round(
- mDisplayMetrics.heightPixels
- * (1 - mBouncerZoneScreenPercentage)),
- mDisplayMetrics.widthPixels,
- mDisplayMetrics.heightPixels),
+ Math.round(height * (1 - mBouncerZoneScreenPercentage)),
+ width,
+ height),
Region.Op.UNION);
}
}
@@ -356,7 +352,7 @@
}
// The animation utils deal in pixel units, rather than expansion height.
- final float viewHeight = mCentralSurfaces.get().getDisplayHeight();
+ final float viewHeight = mTouchSession.getBounds().height();
final float currentHeight = viewHeight * mCurrentExpansion;
final float targetHeight = viewHeight * expansion;
final float expansionHeight = targetHeight - currentHeight;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
index b8b459e..43e4c62 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
@@ -16,6 +16,9 @@
package com.android.systemui.dreams.touch;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import android.graphics.Rect;
import android.graphics.Region;
import android.view.GestureDetector;
import android.view.InputEvent;
@@ -31,6 +34,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.touch.dagger.InputSessionComponent;
import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.util.display.DisplayHelper;
import com.google.common.util.concurrent.ListenableFuture;
@@ -69,7 +73,8 @@
}
final TouchSessionImpl touchSession =
- new TouchSessionImpl(this, touchSessionImpl);
+ new TouchSessionImpl(this, touchSessionImpl.getBounds(),
+ touchSessionImpl);
mActiveTouchSessions.add(touchSession);
completer.set(touchSession);
});
@@ -120,10 +125,13 @@
private final TouchSessionImpl mPredecessor;
private final DreamOverlayTouchMonitor mTouchMonitor;
+ private final Rect mBounds;
- TouchSessionImpl(DreamOverlayTouchMonitor touchMonitor, TouchSessionImpl predecessor) {
+ TouchSessionImpl(DreamOverlayTouchMonitor touchMonitor, Rect bounds,
+ TouchSessionImpl predecessor) {
mPredecessor = predecessor;
mTouchMonitor = touchMonitor;
+ mBounds = bounds;
}
@Override
@@ -185,6 +193,11 @@
private void onRemoved() {
mCallbacks.forEach(callback -> callback.onRemoved());
}
+
+ @Override
+ public Rect getBounds() {
+ return mBounds;
+ }
}
/**
@@ -242,6 +255,7 @@
private final HashSet<TouchSessionImpl> mActiveTouchSessions = new HashSet<>();
private final Collection<DreamTouchHandler> mHandlers;
+ private final DisplayHelper mDisplayHelper;
private InputChannelCompat.InputEventListener mInputEventListener =
new InputChannelCompat.InputEventListener() {
@@ -253,8 +267,11 @@
new HashMap<>();
for (DreamTouchHandler handler : mHandlers) {
+ final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
+ TYPE_APPLICATION_OVERLAY);
+
final Region initiationRegion = Region.obtain();
- handler.getTouchInitiationRegion(initiationRegion);
+ handler.getTouchInitiationRegion(maxBounds, initiationRegion);
if (!initiationRegion.isEmpty()) {
// Initiation regions require a motion event to determine pointer location
@@ -272,8 +289,8 @@
}
}
- final TouchSessionImpl sessionStack =
- new TouchSessionImpl(DreamOverlayTouchMonitor.this, null);
+ final TouchSessionImpl sessionStack = new TouchSessionImpl(
+ DreamOverlayTouchMonitor.this, maxBounds, null);
mActiveTouchSessions.add(sessionStack);
sessionMap.put(handler, sessionStack);
}
@@ -389,11 +406,13 @@
@Main Executor executor,
Lifecycle lifecycle,
InputSessionComponent.Factory inputSessionFactory,
+ DisplayHelper displayHelper,
Set<DreamTouchHandler> handlers) {
mHandlers = handlers;
mInputSessionFactory = inputSessionFactory;
mExecutor = executor;
mLifecycle = lifecycle;
+ mDisplayHelper = displayHelper;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
index 8288fcf..b37010c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
@@ -16,6 +16,7 @@
package com.android.systemui.dreams.touch;
+import android.graphics.Rect;
import android.graphics.Region;
import android.view.GestureDetector;
@@ -77,6 +78,11 @@
* Returns the number of currently active sessions.
*/
int getActiveSessionCount();
+
+ /**
+ * Returns the bounds of the display the touch region.
+ */
+ Rect getBounds();
}
/**
@@ -84,7 +90,7 @@
* indicating the entire screen should be considered.
* @param region A {@link Region} that is passed in to the target entry touch region.
*/
- default void getTouchInitiationRegion(Region region) {
+ default void getTouchInitiationRegion(Rect bounds, Region region) {
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index a9dd260..d4ed546 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -226,7 +226,7 @@
/** Whether to inflate the bouncer view on a background thread. */
// TODO(b/272091103): Tracking Bug
@JvmField
- val ASYNC_INFLATE_BOUNCER = unreleasedFlag(229, "async_inflate_bouncer", teamfood = true)
+ val ASYNC_INFLATE_BOUNCER = unreleasedFlag(229, "async_inflate_bouncer", teamfood = false)
/** Whether to inflate the bouncer view on a background thread. */
// TODO(b/273341787): Tracking Bug
@@ -251,20 +251,12 @@
// TODO(b/270223352): Tracking Bug
@JvmField
val HIDE_SMARTSPACE_ON_DREAM_OVERLAY =
- unreleasedFlag(
- 404,
- "hide_smartspace_on_dream_overlay",
- teamfood = true
- )
+ releasedFlag(404, "hide_smartspace_on_dream_overlay")
// TODO(b/271460958): Tracking Bug
@JvmField
val SHOW_WEATHER_COMPLICATION_ON_DREAM_OVERLAY =
- unreleasedFlag(
- 405,
- "show_weather_complication_on_dream_overlay",
- teamfood = true
- )
+ releasedFlag(405, "show_weather_complication_on_dream_overlay")
// 500 - quick settings
@@ -415,16 +407,21 @@
@JvmField val ROUNDED_BOX_RIPPLE = releasedFlag(1002, "rounded_box_ripple")
// TODO(b/270882464): Tracking Bug
- val ENABLE_DOCK_SETUP_V2 = unreleasedFlag(1005, "enable_dock_setup_v2", teamfood = true)
+ val ENABLE_DOCK_SETUP_V2 = releasedFlag(1005, "enable_dock_setup_v2")
// TODO(b/265045965): Tracking Bug
val SHOW_LOWLIGHT_ON_DIRECT_BOOT = releasedFlag(1003, "show_lowlight_on_direct_boot")
@JvmField
// TODO(b/271428141): Tracking Bug
- val ENABLE_LOW_LIGHT_CLOCK_UNDOCKED = unreleasedFlag(
+ val ENABLE_LOW_LIGHT_CLOCK_UNDOCKED = releasedFlag(
1004,
- "enable_low_light_clock_undocked", teamfood = true)
+ "enable_low_light_clock_undocked")
+
+ // TODO(b/273509374): Tracking Bug
+ @JvmField
+ val ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS = unreleasedFlag(1006,
+ "always_show_home_controls_on_dreams")
// 1100 - windowing
@Keep
@@ -517,7 +514,7 @@
@JvmField
val ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
sysPropBooleanFlag(
- 1116, "persist.wm.debug.enable_move_floating_window_in_tabletop", default = false)
+ 1116, "persist.wm.debug.enable_move_floating_window_in_tabletop", default = true)
// 1200 - predictive back
@Keep
@@ -613,6 +610,9 @@
val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW =
releasedFlag(1504, "sharesheet_scrollable_image_preview")
+ // TODO(b/274137694) Tracking Bug
+ val CHOOSER_MIGRATION_ENABLED = unreleasedFlag(1505, "chooser_migration_enabled")
+
// 1700 - clipboard
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
// TODO(b/267162944): Tracking bug
diff --git a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
index b49d60d..dc0de2c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
@@ -39,15 +39,15 @@
) {
companion object {
- @VisibleForTesting val RESTART_NAP_KEY = "restart_nap_after_start"
+ @VisibleForTesting val RESTART_SLEEP_KEY = "restart_nap_after_start"
}
private var inited = false
val listener =
object : StatusBarStateController.StateListener {
- override fun onDreamingChanged(isDreaming: Boolean) {
- storeSleepState(isDreaming)
+ override fun onDozingChanged(isDozing: Boolean) {
+ storeSleepState(isDozing)
}
}
@@ -67,9 +67,13 @@
fun maybeRestartSleep() {
bgExecutor.executeDelayed(
{
- if (settings.getBool(RESTART_NAP_KEY, false)) {
+ if (settings.getBool(RESTART_SLEEP_KEY, false)) {
Log.d("RestartDozeListener", "Restarting sleep state")
- powerManager.wakeUp(systemClock.uptimeMillis())
+ powerManager.wakeUp(
+ systemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION,
+ "RestartDozeListener"
+ )
powerManager.goToSleep(systemClock.uptimeMillis())
}
},
@@ -78,6 +82,6 @@
}
private fun storeSleepState(sleeping: Boolean) {
- bgExecutor.execute { settings.putBool(RESTART_NAP_KEY, sleeping) }
+ bgExecutor.execute { settings.putBool(RESTART_SLEEP_KEY, sleeping) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 3e52ff2..9ab2e99 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -22,6 +22,7 @@
import android.content.Context
import android.graphics.Matrix
import android.graphics.Rect
+import android.os.DeadObjectException
import android.os.Handler
import android.os.PowerManager
import android.os.RemoteException
@@ -524,10 +525,22 @@
surfaceBehindAlpha = 1f
setSurfaceBehindAppearAmount(1f)
- launcherUnlockController?.playUnlockAnimation(
- true,
- UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY,
- 0 /* startDelay */)
+ try {
+ launcherUnlockController?.playUnlockAnimation(
+ true,
+ UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY,
+ 0 /* startDelay */)
+ } catch (e: DeadObjectException) {
+ // Hello! If you are here investigating a bug where Launcher is blank (no icons)
+ // then the below assumption about Launcher's destruction was incorrect. This
+ // would mean prepareToUnlock was called (blanking Launcher in preparation for
+ // the beginning of the unlock animation), but then somehow we were unable to
+ // call playUnlockAnimation to animate the icons back in.
+ Log.e(TAG, "launcherUnlockAnimationController was dead, but non-null. " +
+ "Catching exception as this should mean Launcher is in the process " +
+ "of being destroyed, but the IPC to System UI telling us hasn't " +
+ "arrived yet.")
+ }
launcherPreparedForUnlock = false
} else {
@@ -604,11 +617,23 @@
private fun unlockToLauncherWithInWindowAnimations() {
setSurfaceBehindAppearAmount(1f)
- // Begin the animation, waiting for the shade to animate out.
- launcherUnlockController?.playUnlockAnimation(
- true /* unlocked */,
- LAUNCHER_ICONS_ANIMATION_DURATION_MS /* duration */,
- CANNED_UNLOCK_START_DELAY /* startDelay */)
+ try {
+ // Begin the animation, waiting for the shade to animate out.
+ launcherUnlockController?.playUnlockAnimation(
+ true /* unlocked */,
+ LAUNCHER_ICONS_ANIMATION_DURATION_MS /* duration */,
+ CANNED_UNLOCK_START_DELAY /* startDelay */)
+ } catch (e: DeadObjectException) {
+ // Hello! If you are here investigating a bug where Launcher is blank (no icons)
+ // then the below assumption about Launcher's destruction was incorrect. This
+ // would mean prepareToUnlock was called (blanking Launcher in preparation for
+ // the beginning of the unlock animation), but then somehow we were unable to
+ // call playUnlockAnimation to animate the icons back in.
+ Log.e(TAG, "launcherUnlockAnimationController was dead, but non-null. " +
+ "Catching exception as this should mean Launcher is in the process " +
+ "of being destroyed, but the IPC to System UI telling us hasn't " +
+ "arrived yet.")
+ }
launcherPreparedForUnlock = false
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 5ecc00f..0825435 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2690,6 +2690,17 @@
mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
return;
}
+ if (apps == null || apps.length == 0) {
+ Slog.e(TAG, "Keyguard exit without a corresponding app to show.");
+ try {
+ finishedCallback.onAnimationFinished();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException");
+ } finally {
+ mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
+ }
+ return;
+ }
// TODO(bc-unlock): Sample animation, just to apply alpha animation on the app.
final SyncRtSurfaceTransactionApplier applier =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index b10aa90..e65c8a1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -303,6 +303,10 @@
/** Tell the bouncer to start the pre hide animation. */
fun startDisappearAnimation(runnable: Runnable) {
+ if (willRunDismissFromKeyguard()) {
+ runnable.run()
+ return
+ }
val finishRunnable = Runnable {
runnable.run()
repository.setPrimaryStartDisappearAnimation(null)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SysUiFaceAuthenticateOptions.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SysUiFaceAuthenticateOptions.kt
index a79513e..942cd60 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SysUiFaceAuthenticateOptions.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SysUiFaceAuthenticateOptions.kt
@@ -31,7 +31,6 @@
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_UNKNOWN
import android.util.Log
-import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.FaceAuthUiEvent
@@ -40,11 +39,11 @@
* [FaceAuthenticateOptions].
*/
data class SysUiFaceAuthenticateOptions(
- val userId: Int,
- private val faceAuthUiEvent: UiEventLogger.UiEventEnum,
- @PowerManager.WakeReason val wakeReason: Int = WAKE_REASON_UNKNOWN
+ val userId: Int,
+ private val faceAuthUiEvent: UiEventLogger.UiEventEnum,
+ @PowerManager.WakeReason val wakeReason: Int = WAKE_REASON_UNKNOWN
) {
- val authenticateReason = setAuthenticateReason(faceAuthUiEvent)
+ private val authenticateReason = setAuthenticateReason(faceAuthUiEvent)
/**
* The [FaceAuthUiEvent] for this operation. This method converts the UiEvent to the framework
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index b23247c..df93d23 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -81,9 +81,7 @@
)
.map {
if (willRunDismissFromKeyguard) {
- ScrimAlpha(
- notificationsAlpha = 1f,
- )
+ ScrimAlpha()
} else if (leaveShadeOpen) {
ScrimAlpha(
behindAlpha = 1f,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 9c7b48d..ab39442 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -39,7 +39,6 @@
import com.android.systemui.R
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -69,7 +68,6 @@
import com.android.systemui.util.traceSection
import java.io.PrintWriter
import java.util.TreeMap
-import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
@@ -95,8 +93,7 @@
private val mediaHostStatesManager: MediaHostStatesManager,
private val activityStarter: ActivityStarter,
private val systemClock: SystemClock,
- @Main private val mainExecutor: DelayableExecutor,
- @Background private val backgroundExecutor: Executor,
+ @Main executor: DelayableExecutor,
private val mediaManager: MediaDataManager,
configurationController: ConfigurationController,
falsingCollector: FalsingCollector,
@@ -109,10 +106,11 @@
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : Dumpable {
/** The current width of the carousel */
- private var currentCarouselWidth: Int = 0
+ var currentCarouselWidth: Int = 0
+ private set
/** The current height of the carousel */
- @VisibleForTesting var currentCarouselHeight: Int = 0
+ private var currentCarouselHeight: Int = 0
/** Are we currently showing only active players */
private var currentlyShowingOnlyActive: Boolean = false
@@ -253,7 +251,7 @@
MediaCarouselScrollHandler(
mediaCarousel,
pageIndicator,
- mainExecutor,
+ executor,
this::onSwipeToDismiss,
this::updatePageIndicatorLocation,
this::updateSeekbarListening,
@@ -615,50 +613,10 @@
MediaPlayerData.visiblePlayerKeys()
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
if (existingPlayer == null) {
- setupNewPlayer(key, data, isSsReactivated, curVisibleMediaKey)
- } else {
- existingPlayer.bindPlayer(data, key)
- MediaPlayerData.addMediaPlayer(
- key,
- data,
- existingPlayer,
- systemClock,
- isSsReactivated,
- debugLogger
- )
- val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String()
- // In case of recommendations hits.
- // Check the playing status of media player and the package name.
- // To make sure we scroll to the right app's media player.
- if (
- isReorderingAllowed ||
- shouldScrollToKey &&
- data.isPlaying == true &&
- packageName == data.packageName
- ) {
- reorderAllPlayers(curVisibleMediaKey, key)
- } else {
- needsReordering = true
- }
- updatePageIndicator()
- mediaCarouselScrollHandler.onPlayersChanged()
- mediaFrame.requiresRemeasuring = true
- }
- return existingPlayer == null
- }
-
- private fun setupNewPlayer(
- key: String,
- data: MediaData,
- isSsReactivated: Boolean,
- curVisibleMediaKey: MediaPlayerData.MediaSortKey?,
- ) {
- backgroundExecutor.execute {
- val mediaViewHolder = createMediaViewHolderInBg()
- // Add the new player in the main thread.
- mainExecutor.execute {
val newPlayer = mediaControlPanelFactory.get()
- newPlayer.attachPlayer(mediaViewHolder)
+ newPlayer.attachPlayer(
+ MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
+ )
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
val lp =
LinearLayout.LayoutParams(
@@ -688,16 +646,36 @@
} else {
needsReordering = true
}
- updatePageIndicator()
- mediaCarouselScrollHandler.onPlayersChanged()
- mediaFrame.requiresRemeasuring = true
+ } else {
+ existingPlayer.bindPlayer(data, key)
+ MediaPlayerData.addMediaPlayer(
+ key,
+ data,
+ existingPlayer,
+ systemClock,
+ isSsReactivated,
+ debugLogger
+ )
+ val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String()
+ // In case of recommendations hits.
+ // Check the playing status of media player and the package name.
+ // To make sure we scroll to the right app's media player.
+ if (
+ isReorderingAllowed ||
+ shouldScrollToKey &&
+ data.isPlaying == true &&
+ packageName == data.packageName
+ ) {
+ reorderAllPlayers(curVisibleMediaKey, key)
+ } else {
+ needsReordering = true
+ }
}
+ updatePageIndicator()
+ mediaCarouselScrollHandler.onPlayersChanged()
+ mediaFrame.requiresRemeasuring = true
+ return existingPlayer == null
}
- }
-
- private fun createMediaViewHolderInBg(): MediaViewHolder {
- return MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
- }
private fun addSmartspaceMediaRecommendations(
key: String,
@@ -731,14 +709,15 @@
debugLogger.logPotentialMemoryLeak(existingSmartspaceMediaKey)
}
}
+
val newRecs = mediaControlPanelFactory.get()
- val recommendationViewHolder =
+ newRecs.attachRecommendation(
RecommendationViewHolder.create(
LayoutInflater.from(context),
mediaContent,
mediaFlags.isRecommendationCardUpdateEnabled()
)
- newRecs.attachRecommendation(recommendationViewHolder)
+ )
newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
val lp =
LinearLayout.LayoutParams(
@@ -762,6 +741,17 @@
reorderAllPlayers(curVisibleMediaKey)
updatePageIndicator()
mediaFrame.requiresRemeasuring = true
+ // Check postcondition: mediaContent should have the same number of children as there
+ // are
+ // elements in mediaPlayers.
+ if (MediaPlayerData.players().size != mediaContent.childCount) {
+ Log.e(
+ TAG,
+ "Size of players list and number of views in carousel are out of sync. " +
+ "Players size is ${MediaPlayerData.players().size}. " +
+ "View count is ${mediaContent.childCount}."
+ )
+ }
}
fun removePlayer(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 15d999a..cb1f12cf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -32,6 +32,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
@@ -54,6 +56,7 @@
import android.os.Trace;
import android.text.TextUtils;
import android.util.Log;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -468,6 +471,7 @@
TransitionLayout recommendations = vh.getRecommendations();
mMediaViewController.attach(recommendations, MediaViewController.TYPE.RECOMMENDATION);
+ mMediaViewController.configurationChangeListener = this::updateRecommendationsVisibility;
mRecommendationViewHolder.getRecommendations().setOnLongClickListener(v -> {
if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) return true;
@@ -1364,6 +1368,7 @@
boolean hasTitle = false;
boolean hasSubtitle = false;
+ int fittedRecsNum = getNumberOfFittedRecommendations();
for (int itemIndex = 0; itemIndex < NUM_REQUIRED_RECOMMENDATIONS; itemIndex++) {
SmartspaceAction recommendation = recommendations.get(itemIndex);
@@ -1444,12 +1449,20 @@
// If there's no subtitles and/or titles for any of the albums, hide those views.
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
final boolean titlesVisible = hasTitle;
final boolean subtitlesVisible = hasSubtitle;
- mRecommendationViewHolder.getMediaTitles().forEach((titleView) ->
- setVisibleAndAlpha(expandedSet, titleView.getId(), titlesVisible));
- mRecommendationViewHolder.getMediaSubtitles().forEach((subtitleView) ->
- setVisibleAndAlpha(expandedSet, subtitleView.getId(), subtitlesVisible));
+ mRecommendationViewHolder.getMediaTitles().forEach((titleView) -> {
+ setVisibleAndAlpha(expandedSet, titleView.getId(), titlesVisible);
+ setVisibleAndAlpha(collapsedSet, titleView.getId(), titlesVisible);
+ });
+ mRecommendationViewHolder.getMediaSubtitles().forEach((subtitleView) -> {
+ setVisibleAndAlpha(expandedSet, subtitleView.getId(), subtitlesVisible);
+ setVisibleAndAlpha(collapsedSet, subtitleView.getId(), subtitlesVisible);
+ });
+
+ // Media covers visibility.
+ setMediaCoversVisibility(fittedRecsNum);
// Guts
Runnable onDismissClickedRunnable = () -> {
@@ -1486,6 +1499,51 @@
Trace.endSection();
}
+ private Unit updateRecommendationsVisibility() {
+ int fittedRecsNum = getNumberOfFittedRecommendations();
+ setMediaCoversVisibility(fittedRecsNum);
+ return Unit.INSTANCE;
+ }
+
+ private void setMediaCoversVisibility(int fittedRecsNum) {
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
+ List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
+ // Hide media cover that cannot fit in the recommendation card.
+ for (int itemIndex = 0; itemIndex < NUM_REQUIRED_RECOMMENDATIONS; itemIndex++) {
+ setVisibleAndAlpha(expandedSet, mediaCoverContainers.get(itemIndex).getId(),
+ itemIndex < fittedRecsNum);
+ setVisibleAndAlpha(collapsedSet, mediaCoverContainers.get(itemIndex).getId(),
+ itemIndex < fittedRecsNum);
+ }
+ }
+
+ @VisibleForTesting
+ protected int getNumberOfFittedRecommendations() {
+ Resources res = mContext.getResources();
+ Configuration config = res.getConfiguration();
+ int defaultDpWidth = res.getInteger(R.integer.default_qs_media_rec_width_dp);
+ int recCoverWidth = res.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
+ + res.getDimensionPixelSize(R.dimen.qs_media_info_spacing) * 2;
+
+ // On landscape, media controls should take half of the screen width.
+ int displayAvailableDpWidth = config.screenWidthDp;
+ if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ displayAvailableDpWidth = displayAvailableDpWidth / 2;
+ }
+ int fittedNum;
+ if (displayAvailableDpWidth > defaultDpWidth) {
+ int recCoverDefaultWidth = res.getDimensionPixelSize(
+ R.dimen.qs_media_rec_default_width);
+ fittedNum = recCoverDefaultWidth / recCoverWidth;
+ } else {
+ int displayAvailableWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ displayAvailableDpWidth, res.getDisplayMetrics());
+ fittedNum = displayAvailableWidth / recCoverWidth;
+ }
+ return Math.min(fittedNum, NUM_REQUIRED_RECOMMENDATIONS);
+ }
+
private void fetchAndUpdateRecommendationColors(Drawable appIcon) {
mBackgroundExecutor.execute(() -> {
ColorScheme colorScheme = new ColorScheme(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 7a1302c..cd51d92 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -96,6 +96,7 @@
/** A listener when the current dimensions of the player change */
lateinit var sizeChangedListener: () -> Unit
+ lateinit var configurationChangeListener: () -> Unit
private var firstRefresh: Boolean = true
@VisibleForTesting private var transitionLayout: TransitionLayout? = null
private val layoutController = TransitionLayoutController()
@@ -195,6 +196,10 @@
)
}
}
+ if (this@MediaViewController::configurationChangeListener.isInitialized) {
+ configurationChangeListener.invoke()
+ refreshState()
+ }
}
}
}
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 b71a9193..9928c4f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -16,10 +16,6 @@
package com.android.systemui.media.dialog;
-import static android.media.RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED;
-import static android.media.RouteListingPreference.Item.SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED;
-import static android.media.RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED;
-
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_GO_TO_APP;
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_NONE;
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
@@ -344,7 +340,7 @@
updateDeviceStatusIcon(deviceStatusIcon);
mStatusIcon.setVisibility(View.VISIBLE);
}
- updateTwoLineLayoutContentAlpha(
+ updateSingleLineLayoutContentAlpha(
updateClickActionBasedOnSelectionBehavior(device)
? DEVICE_CONNECTED_ALPHA : DEVICE_DISCONNECTED_ALPHA);
} else {
@@ -368,6 +364,12 @@
mStatusIcon.setAlpha(alphaValue);
}
+ private void updateSingleLineLayoutContentAlpha(float alphaValue) {
+ mTitleIcon.setAlpha(alphaValue);
+ mTitleText.setAlpha(alphaValue);
+ mStatusIcon.setAlpha(alphaValue);
+ }
+
private void updateEndClickAreaAsSessionEditing(MediaDevice device) {
mEndClickIcon.setOnClickListener(null);
mEndTouchArea.setOnClickListener(null);
@@ -535,11 +537,12 @@
@DoNotInline
static Drawable getDeviceStatusIconBasedOnSelectionBehavior(MediaDevice device,
Context context) {
- switch (device.getSubtext()) {
- case SUBTEXT_AD_ROUTING_DISALLOWED:
- case SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED:
+ switch (device.getSelectionBehavior()) {
+ case SELECTION_BEHAVIOR_NONE:
return context.getDrawable(R.drawable.media_output_status_failed);
- case SUBTEXT_SUBSCRIPTION_REQUIRED:
+ case SELECTION_BEHAVIOR_TRANSFER:
+ return null;
+ case SELECTION_BEHAVIOR_GO_TO_APP:
return context.getDrawable(R.drawable.media_output_status_help);
}
return null;
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 f76f049..f92a5ab 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -192,8 +192,11 @@
mSubTitleText.setTextColor(mController.getColorItemContent());
mTwoLineTitleText.setTextColor(mController.getColorItemContent());
if (mController.isAdvancedLayoutSupported()) {
- mIconAreaLayout.setOnClickListener(null);
mVolumeValueText.setTextColor(mController.getColorItemContent());
+ mTitleIcon.setOnTouchListener(((v, event) -> {
+ mSeekBar.dispatchTouchEvent(event);
+ return false;
+ }));
}
mSeekBar.setProgressTintList(
ColorStateList.valueOf(mController.getColorSeekbarProgress()));
@@ -444,9 +447,6 @@
}
void updateIconAreaClickListener(View.OnClickListener listener) {
- if (mController.isAdvancedLayoutSupported()) {
- mIconAreaLayout.setOnClickListener(listener);
- }
mTitleIcon.setOnClickListener(listener);
}
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 2aedd36..f3f17d1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -395,7 +395,6 @@
launchIntent.putExtra(EXTRA_ROUTE_ID, routeId);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mCallback.dismissDialog();
- mContext.startActivity(launchIntent);
mActivityStarter.startActivity(launchIntent, true, controller);
}
}
@@ -996,7 +995,7 @@
mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags);
MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true,
broadcastSender, controller);
- mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
+ dialog.show();
}
String getBroadcastName() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
index 760a42c..132bf99 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
@@ -62,7 +62,8 @@
private fun launchMediaOutputBroadcastDialogIfPossible(packageName: String?) {
if (!packageName.isNullOrEmpty()) {
- mediaOutputBroadcastDialogFactory.create(packageName, false)
+ mediaOutputBroadcastDialogFactory.create(
+ packageName, aboveStatusBar = true, view = null)
} else if (DEBUG) {
Log.e(TAG, "Unable to launch media output broadcast dialog. Package name is empty.")
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
index 253c3c7..be5d607 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
@@ -26,6 +26,7 @@
*/
public class MediaOutputSeekbar extends SeekBar {
private static final int SCALE_SIZE = 1000;
+ private static final int INITIAL_PROGRESS = 500;
public static final int VOLUME_PERCENTAGE_SCALE_SIZE = 100000;
public MediaOutputSeekbar(Context context, AttributeSet attrs) {
@@ -38,7 +39,7 @@
}
static int scaleVolumeToProgress(int volume) {
- return volume * SCALE_SIZE;
+ return volume == 0 ? 0 : INITIAL_PROGRESS + volume * SCALE_SIZE;
}
int getVolume() {
@@ -46,7 +47,7 @@
}
void setVolume(int volume) {
- setProgress(volume * SCALE_SIZE, true);
+ setProgress(scaleVolumeToProgress(volume), true);
}
void setMaxVolume(int maxVolume) {
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
index 9bccb7d..89f66b7 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProvider.kt
@@ -19,12 +19,11 @@
import android.content.Context
import android.content.res.Configuration
import android.graphics.Rect
+import android.view.WindowInsets.Type
import android.view.WindowManager
-import com.android.internal.R as AndroidR
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope
import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider.TaskPreviewSizeListener
import com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen
-import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
@@ -62,17 +61,12 @@
val width = windowMetrics.bounds.width()
var height = maximumWindowHeight
- // TODO(b/271410803): Read isTransientTaskbar from Launcher
val isLargeScreen = isLargeScreen(context)
- val isTransientTaskbar =
- QuickStepContract.isGesturalMode(
- context.resources.getInteger(
- com.android.internal.R.integer.config_navBarInteractionMode
- )
- )
- if (isLargeScreen && !isTransientTaskbar) {
+ if (isLargeScreen) {
val taskbarSize =
- context.resources.getDimensionPixelSize(AndroidR.dimen.taskbar_frame_height)
+ windowManager.currentWindowMetrics.windowInsets
+ .getInsets(Type.tappableElement())
+ .bottom
height -= taskbarSize
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 8a5bac8..44c718f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -159,6 +159,8 @@
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.pip.Pip;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Map;
@@ -167,8 +169,6 @@
import javax.inject.Inject;
-import dagger.Lazy;
-
/**
* Contains logic for a navigation bar view.
*/
@@ -245,12 +245,6 @@
private boolean mTransientShown;
private boolean mTransientShownFromGestureOnSystemBar;
- /**
- * This is to indicate whether the navigation bar button is forced visible. This is true
- * when the setup wizard is on display. When that happens, the window frame should be provided
- * as insets size directly.
- */
- private boolean mIsButtonForceVisible;
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
private LightBarController mLightBarController;
private final LightBarController mMainLightBarController;
@@ -679,8 +673,7 @@
mView.setTouchHandler(mTouchHandler);
setNavBarMode(mNavBarMode);
mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
- mEdgeBackGestureHandler.setButtonForceVisibleChangeCallback((forceVisible) -> {
- mIsButtonForceVisible = forceVisible;
+ mEdgeBackGestureHandler.setButtonForcedVisibleChangeCallback((forceVisible) -> {
repositionNavigationBar(mCurrentRotation);
});
mNavigationBarTransitions.addListener(this::onBarTransition);
@@ -1721,7 +1714,7 @@
.setInsetsSizeOverrides(new InsetsFrameProvider.InsetsSizeOverride[] {
new InsetsFrameProvider.InsetsSizeOverride(
TYPE_INPUT_METHOD, null)});
- if (insetsHeight != -1 && !mIsButtonForceVisible) {
+ if (insetsHeight != -1 && !mEdgeBackGestureHandler.isButtonForcedVisible()) {
navBarProvider.setInsetsSize(Insets.of(0, 0, 0, insetsHeight));
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index e7bb6dc..0d5a3fd 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -58,12 +58,14 @@
private const val MIN_DURATION_CANCELLED_ANIMATION = 200L
private const val MIN_DURATION_COMMITTED_ANIMATION = 120L
private const val MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION = 50L
+private const val MIN_DURATION_FLING_ANIMATION = 160L
private const val MIN_DURATION_ENTRY_TO_ACTIVE_CONSIDERED_AS_FLING = 100L
private const val MIN_DURATION_INACTIVE_TO_ACTIVE_CONSIDERED_AS_FLING = 400L
private const val FAILSAFE_DELAY_MS = 350L
-private const val POP_ON_FLING_DELAY = 140L
+private const val POP_ON_FLING_DELAY = 50L
+private const val POP_ON_FLING_SCALE = 3f
internal val VIBRATE_ACTIVATED_EFFECT =
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)
@@ -230,7 +232,12 @@
updateArrowState(GestureState.GONE)
}
- private val playAnimationThenSetGoneOnAlphaEnd = Runnable { playAnimationThenSetGoneEnd() }
+ private val onAlphaEndSetGoneStateListener = DelayedOnAnimationEndListener(mainHandler, 0L) {
+ updateRestingArrowDimens()
+ if (!mView.addAnimationEndListener(mView.backgroundAlpha, onEndSetGoneStateListener)) {
+ scheduleFailsafe()
+ }
+ }
// Minimum of the screen's width or the predefined threshold
private var fullyStretchedThreshold = 0f
@@ -357,7 +364,7 @@
mView.cancelAnimations()
mainHandler.removeCallbacks(onEndSetCommittedStateListener.runnable)
mainHandler.removeCallbacks(onEndSetGoneStateListener.runnable)
- mainHandler.removeCallbacks(playAnimationThenSetGoneOnAlphaEnd)
+ mainHandler.removeCallbacks(onAlphaEndSetGoneStateListener.runnable)
}
/**
@@ -509,7 +516,7 @@
val maxYOffset = (mView.height - params.entryIndicator.backgroundDimens.height) / 2f
val rubberbandAmount = 15f
val yProgress = MathUtils.saturate(yTranslation / (maxYOffset * rubberbandAmount))
- val yPosition = params.translationInterpolator.getInterpolation(yProgress) *
+ val yPosition = params.verticalTranslationInterpolator.getInterpolation(yProgress) *
maxYOffset *
sign(yOffset)
mView.animateVertically(yPosition)
@@ -520,10 +527,9 @@
* the arrow is fully stretched (between 0.0 - 1.0f)
*/
private fun fullScreenProgress(xTranslation: Float): Float {
- return MathUtils.saturate(
- (xTranslation - previousXTranslationOnActiveOffset) /
- (fullyStretchedThreshold - previousXTranslationOnActiveOffset)
- )
+ val progress = abs((xTranslation - previousXTranslationOnActiveOffset) /
+ (fullyStretchedThreshold - previousXTranslationOnActiveOffset))
+ return MathUtils.saturate(progress)
}
/**
@@ -540,7 +546,7 @@
private fun stretchActiveBackIndicator(progress: Float) {
mView.setStretch(
- horizontalTranslationStretchAmount = params.translationInterpolator
+ horizontalTranslationStretchAmount = params.horizontalTranslationInterpolator
.getInterpolation(progress),
arrowStretchAmount = params.arrowAngleInterpolator.getInterpolation(progress),
backgroundWidthStretchAmount = params.activeWidthInterpolator
@@ -639,20 +645,6 @@
return flingDistance > minFlingDistance && isPastFlingVelocityThreshold
}
- private fun playHorizontalAnimationThen(onEnd: DelayedOnAnimationEndListener) {
- updateRestingArrowDimens()
- if (!mView.addAnimationEndListener(mView.horizontalTranslation, onEnd)) {
- scheduleFailsafe()
- }
- }
-
- private fun playAnimationThenSetGoneEnd() {
- updateRestingArrowDimens()
- if (!mView.addAnimationEndListener(mView.backgroundAlpha, onEndSetGoneStateListener)) {
- scheduleFailsafe()
- }
- }
-
private fun playWithBackgroundWidthAnimation(
onEnd: DelayedOnAnimationEndListener,
delay: Long = 0L
@@ -912,18 +904,25 @@
updateRestingArrowDimens()
}
GestureState.FLUNG -> {
- mainHandler.postDelayed(POP_ON_FLING_DELAY) { mView.popScale(1.9f) }
- playHorizontalAnimationThen(onEndSetCommittedStateListener)
+ mainHandler.postDelayed(POP_ON_FLING_DELAY) { mView.popScale(POP_ON_FLING_SCALE) }
+ updateRestingArrowDimens()
+ mainHandler.postDelayed(onEndSetCommittedStateListener.runnable,
+ MIN_DURATION_FLING_ANIMATION)
}
GestureState.COMMITTED -> {
+ // In most cases, animating between states is handled via `updateRestingArrowDimens`
+ // which plays an animation immediately upon state change. Some animations however
+ // occur after a delay upon state change and these animations may be independent
+ // or non-sequential from the state change animation. `postDelayed` is used to
+ // manually play these kinds of animations in parallel.
if (previousState == GestureState.FLUNG) {
- playAnimationThenSetGoneEnd()
+ updateRestingArrowDimens()
+ mainHandler.postDelayed(onEndSetGoneStateListener.runnable,
+ MIN_DURATION_COMMITTED_ANIMATION)
} else {
- mView.popScale(3f)
- mainHandler.postDelayed(
- playAnimationThenSetGoneOnAlphaEnd,
- MIN_DURATION_COMMITTED_ANIMATION
- )
+ mView.popScale(POP_ON_FLING_SCALE)
+ mainHandler.postDelayed(onAlphaEndSetGoneStateListener.runnable,
+ MIN_DURATION_COMMITTED_ANIMATION)
}
}
GestureState.CANCELLED -> {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index cfcc671..498d5c0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -18,7 +18,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
-import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;
+import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -177,7 +177,7 @@
private final OverviewProxyService mOverviewProxyService;
private final SysUiState mSysUiState;
private Runnable mStateChangeCallback;
- private Consumer<Boolean> mButtonForceVisibleCallback;
+ private Consumer<Boolean> mButtonForcedVisibleCallback;
private final PluginManager mPluginManager;
private final ProtoTracer mProtoTracer;
@@ -244,8 +244,8 @@
private boolean mIsBackGestureAllowed;
private boolean mGestureBlockingActivityRunning;
private boolean mIsNewBackAffordanceEnabled;
- private boolean mIsTrackpadGestureBackEnabled;
- private boolean mIsButtonForceVisible;
+ private boolean mIsTrackpadGestureFeaturesEnabled;
+ private boolean mIsButtonForcedVisible;
private InputMonitor mInputMonitor;
private InputChannelCompat.InputEventReceiver mInputEventReceiver;
@@ -412,8 +412,8 @@
mStateChangeCallback = callback;
}
- public void setButtonForceVisibleChangeCallback(Consumer<Boolean> callback) {
- mButtonForceVisibleCallback = callback;
+ public void setButtonForcedVisibleChangeCallback(Consumer<Boolean> callback) {
+ mButtonForcedVisibleCallback = callback;
}
public int getEdgeWidthLeft() {
@@ -428,13 +428,14 @@
Resources res = mNavigationModeController.getCurrentUserContext().getResources();
mEdgeWidthLeft = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
mEdgeWidthRight = mGestureNavigationSettingsObserver.getRightSensitivity(res);
- final boolean previousForceVisible = mIsButtonForceVisible;
- mIsButtonForceVisible =
+ final boolean previousForcedVisible = mIsButtonForcedVisible;
+ mIsButtonForcedVisible =
mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
- if (previousForceVisible != mIsButtonForceVisible && mButtonForceVisibleCallback != null) {
- mButtonForceVisibleCallback.accept(mIsButtonForceVisible);
+ if (previousForcedVisible != mIsButtonForcedVisible
+ && mButtonForcedVisibleCallback != null) {
+ mButtonForcedVisibleCallback.accept(mIsButtonForcedVisible);
}
- mIsBackGestureAllowed = !mIsButtonForceVisible;
+ mIsBackGestureAllowed = !mIsButtonForcedVisible;
final DisplayMetrics dm = res.getDisplayMetrics();
final float defaultGestureHeight = res.getDimension(
@@ -590,7 +591,7 @@
// Add a nav bar panel window
mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
- mIsTrackpadGestureBackEnabled = mFeatureFlags.isEnabled(
+ mIsTrackpadGestureFeaturesEnabled = mFeatureFlags.isEnabled(
Flags.TRACKPAD_GESTURE_FEATURES);
resetEdgeBackPlugin();
mPluginManager.addPluginListener(
@@ -635,6 +636,10 @@
return mIsEnabled && mIsBackGestureAllowed;
}
+ public boolean isButtonForcedVisible() {
+ return mIsButtonForcedVisible;
+ }
+
/**
* Update the PiP bounds, used for exclusion calculation.
*/
@@ -883,7 +888,7 @@
}
private void onMotionEvent(MotionEvent ev) {
- boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
+ boolean isTrackpadEvent = isTrackpadThreeFingerSwipe(mIsTrackpadGestureFeaturesEnabled, ev);
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG_MISSING_GESTURE) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index 3dc6d2f..35b6c15 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -2,6 +2,7 @@
import android.content.res.Resources
import android.util.TypedValue
+import androidx.core.animation.Interpolator
import androidx.core.animation.PathInterpolator
import androidx.dynamicanimation.animation.SpringForce
import com.android.systemui.R
@@ -77,21 +78,23 @@
var swipeProgressThreshold: Float = 0f
private set
- lateinit var entryWidthInterpolator: PathInterpolator
+ lateinit var entryWidthInterpolator: Interpolator
private set
- lateinit var entryWidthTowardsEdgeInterpolator: PathInterpolator
+ lateinit var entryWidthTowardsEdgeInterpolator: Interpolator
private set
- lateinit var activeWidthInterpolator: PathInterpolator
+ lateinit var activeWidthInterpolator: Interpolator
private set
- lateinit var arrowAngleInterpolator: PathInterpolator
+ lateinit var arrowAngleInterpolator: Interpolator
private set
- lateinit var translationInterpolator: PathInterpolator
+ lateinit var horizontalTranslationInterpolator: Interpolator
private set
- lateinit var farCornerInterpolator: PathInterpolator
+ lateinit var verticalTranslationInterpolator: Interpolator
private set
- lateinit var edgeCornerInterpolator: PathInterpolator
+ lateinit var farCornerInterpolator: Interpolator
private set
- lateinit var heightInterpolator: PathInterpolator
+ lateinit var edgeCornerInterpolator: Interpolator
+ private set
+ lateinit var heightInterpolator: Interpolator
private set
init {
@@ -125,9 +128,10 @@
entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f)
entryWidthTowardsEdgeInterpolator = PathInterpolator(1f, -3f, 1f, 1.2f)
- activeWidthInterpolator = PathInterpolator(.7f, .06f, .34f, .97f)
+ activeWidthInterpolator = PathInterpolator(.56f, -0.39f, .18f, 1.46f)
arrowAngleInterpolator = entryWidthInterpolator
- translationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
+ horizontalTranslationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
+ verticalTranslationInterpolator = PathInterpolator(.5f, 1.15f, .41f, .94f)
farCornerInterpolator = PathInterpolator(.03f, .19f, .14f, 1.09f)
edgeCornerInterpolator = PathInterpolator(0f, 1.11f, .85f, .84f)
heightInterpolator = PathInterpolator(1f, .05f, .9f, -0.29f)
@@ -147,7 +151,7 @@
scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
horizontalTranslationSpring = entryActiveHorizontalTranslationSpring,
- verticalTranslationSpring = createSpring(10000f, 0.9f),
+ verticalTranslationSpring = createSpring(30000f, 1f),
scaleSpring = createSpring(120f, 0.8f),
arrowDimens = ArrowDimens(
length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
@@ -174,7 +178,6 @@
height = getDimen(R.dimen.navigation_edge_entry_background_height),
edgeCornerRadius = getDimen(R.dimen.navigation_edge_entry_edge_corners),
farCornerRadius = getDimen(R.dimen.navigation_edge_entry_far_corners),
- alphaSpring = createSpring(1100f, 1f),
widthSpring = createSpring(450f, 0.65f),
heightSpring = createSpring(1500f, 0.45f),
farCornerRadiusSpring = createSpring(300f, 0.5f),
@@ -269,10 +272,10 @@
heightSpring = flungCommittedHeightSpring,
edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
farCornerRadiusSpring = flungCommittedFarCornerSpring,
- alphaSpring = createSpring(1100f, 1f),
+ alphaSpring = createSpring(1400f, 1f),
),
scale = 0.85f,
- scaleSpring = createSpring(1150f, 1f),
+ scaleSpring = createSpring(6000f, 1f),
)
flungIndicator = committedIndicator.copy(
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
index 1345c9b..9e2b6d3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
@@ -22,9 +22,10 @@
public final class Utilities {
- public static boolean isTrackpadMotionEvent(boolean isTrackpadGestureBackEnabled,
+ public static boolean isTrackpadThreeFingerSwipe(boolean isTrackpadGestureFeaturesEnabled,
MotionEvent event) {
- return isTrackpadGestureBackEnabled
- && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
+ return isTrackpadGestureFeaturesEnabled
+ && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE
+ && event.getPointerCount() == 3;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/InternalNoteTaskApi.kt b/packages/SystemUI/src/com/android/systemui/notetask/InternalNoteTaskApi.kt
new file mode 100644
index 0000000..5d03218
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/InternalNoteTaskApi.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.notetask
+
+/**
+ * Marks declarations that are **internal** in note task API, which means that should not be used
+ * outside of `com.android.systemui.notetask`.
+ */
+@Retention(value = AnnotationRetention.BINARY)
+@Target(
+ AnnotationTarget.CLASS,
+ AnnotationTarget.FUNCTION,
+ AnnotationTarget.TYPEALIAS,
+ AnnotationTarget.PROPERTY
+)
+@RequiresOptIn(
+ level = RequiresOptIn.Level.ERROR,
+ message = "This is an internal API, do not it outside `com.android.systemui.notetask`",
+)
+internal annotation class InternalNoteTaskApi
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 58ac5b3..93ed859 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -14,18 +14,21 @@
* limitations under the License.
*/
+@file:OptIn(InternalNoteTaskApi::class)
+
package com.android.systemui.notetask
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
+import android.app.role.OnRoleHoldersChangedListener
+import android.app.role.RoleManager
+import android.app.role.RoleManager.ROLE_NOTES
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
-import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
-import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
-import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager
+import android.content.pm.ShortcutManager
import android.os.Build
import android.os.UserHandle
import android.os.UserManager
@@ -33,6 +36,8 @@
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
+import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
+import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.kotlin.getOrNull
@@ -55,6 +60,8 @@
@Inject
constructor(
private val context: Context,
+ private val roleManager: RoleManager,
+ private val shortcutManager: ShortcutManager,
private val resolver: NoteTaskInfoResolver,
private val eventLogger: NoteTaskEventLogger,
private val optionalBubbles: Optional<Bubbles>,
@@ -133,7 +140,7 @@
infoReference.set(info)
// TODO(b/266686199): We should handle when app not available. For now, we log.
- val intent = createNoteIntent(info)
+ val intent = createNoteTaskIntent(info)
try {
logDebug { "onShowNoteTask - start: $info on user#${user.identifier}" }
when (info.launchMode) {
@@ -182,30 +189,71 @@
logDebug { "setNoteTaskShortcutEnabled - completed: $isEnabled" }
}
+ /**
+ * Updates all [NoteTaskController] related information, including but not exclusively the
+ * widget shortcut created by the [user] - by default it will use the current user.
+ *
+ * Keep in mind the shortcut API has a
+ * [rate limiting](https://developer.android.com/develop/ui/views/launch/shortcuts/managing-shortcuts#rate-limiting)
+ * and may not be updated in real-time. To reduce the chance of stale shortcuts, we run the
+ * function during System UI initialization.
+ */
+ fun updateNoteTaskAsUser(user: UserHandle) {
+ val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
+ val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty()
+
+ setNoteTaskShortcutEnabled(hasNotesRoleHolder)
+
+ if (hasNotesRoleHolder) {
+ shortcutManager.enableShortcuts(listOf(SHORTCUT_ID))
+ val updatedShortcut = roleManager.createNoteShortcutInfoAsUser(context, user)
+ shortcutManager.updateShortcuts(listOf(updatedShortcut))
+ } else {
+ shortcutManager.disableShortcuts(listOf(SHORTCUT_ID))
+ }
+ }
+
+ /** @see OnRoleHoldersChangedListener */
+ fun onRoleHoldersChanged(roleName: String, user: UserHandle) {
+ if (roleName == ROLE_NOTES) updateNoteTaskAsUser(user)
+ }
+
companion object {
val TAG = NoteTaskController::class.simpleName.orEmpty()
+
+ const val SHORTCUT_ID = "note_task_shortcut_id"
+
+ /**
+ * Shortcut extra which can point to a package name and can be used to indicate an alternate
+ * badge info. Launcher only reads this if the shortcut comes from a system app.
+ *
+ * Duplicated from [com.android.launcher3.icons.IconCache].
+ *
+ * @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
+ */
+ const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
}
}
-private fun createNoteIntent(info: NoteTaskInfo): Intent =
+/** Creates an [Intent] for [ROLE_NOTES]. */
+private fun createNoteTaskIntent(info: NoteTaskInfo): Intent =
Intent(Intent.ACTION_CREATE_NOTE).apply {
setPackage(info.packageName)
// EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint
- // was used to start it.
+ // was used to start the note task.
putExtra(Intent.EXTRA_USE_STYLUS_MODE, true)
- addFlags(FLAG_ACTIVITY_NEW_TASK)
- // We should ensure the note experience can be open both as a full screen (lock screen)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ // We should ensure the note experience can be opened both as a full screen (lockscreen)
// and inside the app bubble (contextual). These additional flags will do that.
if (info.launchMode == NoteTaskLaunchMode.Activity) {
- addFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
- addFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
+ addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
}
}
-private inline fun logDebug(message: () -> String) {
- if (Build.IS_DEBUGGABLE) {
- Log.d(NoteTaskController.TAG, message())
- }
+/** [Log.println] a [Log.DEBUG] message, only when [Build.IS_DEBUGGABLE]. */
+private inline fun Any.logDebug(message: () -> String) {
+ if (Build.IS_DEBUGGABLE) Log.d(this::class.java.simpleName.orEmpty(), message())
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt
index 8ecf081..616f9b5 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt
@@ -14,13 +14,17 @@
* limitations under the License.
*/
+@file:OptIn(InternalNoteTaskApi::class)
+
package com.android.systemui.notetask
import android.app.role.RoleManager
+import android.app.role.RoleManager.ROLE_NOTES
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags
import android.os.UserHandle
import android.util.Log
+import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
@@ -36,10 +40,9 @@
entryPoint: NoteTaskEntryPoint? = null,
isKeyguardLocked: Boolean = false,
): NoteTaskInfo? {
- // TODO(b/267634412): Select UserHandle depending on where the user initiated note-taking.
val user = userTracker.userHandle
- val packageName =
- roleManager.getRoleHoldersAsUser(RoleManager.ROLE_NOTES, user).firstOrNull()
+
+ val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
if (packageName.isNullOrEmpty()) return null
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
index fb3c0cb..04ed08b 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
@@ -15,11 +15,15 @@
*/
package com.android.systemui.notetask
+import android.app.role.RoleManager
+import android.os.UserHandle
import android.view.KeyEvent
import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.CommandQueue
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
+import java.util.concurrent.Executor
import javax.inject.Inject
/** Class responsible to "glue" all note task dependencies. */
@@ -27,8 +31,10 @@
@Inject
constructor(
private val controller: NoteTaskController,
+ private val roleManager: RoleManager,
private val commandQueue: CommandQueue,
private val optionalBubbles: Optional<Bubbles>,
+ @Background private val backgroundExecutor: Executor,
@NoteTaskEnabledKey private val isEnabled: Boolean,
) {
@@ -43,11 +49,15 @@
}
fun initialize() {
- controller.setNoteTaskShortcutEnabled(isEnabled)
-
// Guard against feature not being enabled or mandatory dependencies aren't available.
if (!isEnabled || optionalBubbles.isEmpty) return
+ controller.setNoteTaskShortcutEnabled(true)
commandQueue.addCallback(callbacks)
+ roleManager.addOnRoleHoldersChangedListenerAsUser(
+ backgroundExecutor,
+ controller::onRoleHoldersChanged,
+ UserHandle.ALL,
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
new file mode 100644
index 0000000..441b9f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskRoleManagerExt.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 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.notetask
+
+import android.app.role.RoleManager
+import android.app.role.RoleManager.ROLE_NOTES
+import android.content.Context
+import android.content.pm.ShortcutInfo
+import android.graphics.drawable.Icon
+import android.os.PersistableBundle
+import android.os.UserHandle
+import com.android.systemui.R
+import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
+
+/** Extension functions for [RoleManager] used **internally** by note task. */
+@InternalNoteTaskApi
+internal object NoteTaskRoleManagerExt {
+
+ /**
+ * Gets package name of the default (first) app holding the [role]. If none, returns either an
+ * empty string or null.
+ */
+ fun RoleManager.getDefaultRoleHolderAsUser(role: String, user: UserHandle): String? =
+ getRoleHoldersAsUser(role, user).firstOrNull()
+
+ /** Creates a [ShortcutInfo] for [ROLE_NOTES]. */
+ fun RoleManager.createNoteShortcutInfoAsUser(
+ context: Context,
+ user: UserHandle,
+ ): ShortcutInfo {
+ val extras = PersistableBundle()
+ getDefaultRoleHolderAsUser(ROLE_NOTES, user)?.let { packageName ->
+ // Set custom app badge using the icon from ROLES_NOTES default app.
+ extras.putString(NoteTaskController.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, packageName)
+ }
+
+ val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
+
+ return ShortcutInfo.Builder(context, NoteTaskController.SHORTCUT_ID)
+ .setIntent(LaunchNoteTaskActivity.newIntent(context = context))
+ .setShortLabel(context.getString(R.string.note_task_button_label))
+ .setLongLived(true)
+ .setIcon(icon)
+ .setExtras(extras)
+ .build()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
index 5c59532..0cfb0a5 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/CreateNoteTaskShortcutActivity.kt
@@ -14,19 +14,17 @@
* limitations under the License.
*/
+@file:OptIn(InternalNoteTaskApi::class)
+
package com.android.systemui.notetask.shortcut
import android.app.Activity
import android.app.role.RoleManager
-import android.content.Intent
+import android.content.pm.ShortcutManager
import android.os.Bundle
-import android.os.PersistableBundle
import androidx.activity.ComponentActivity
-import androidx.annotation.DrawableRes
-import androidx.core.content.pm.ShortcutInfoCompat
-import androidx.core.content.pm.ShortcutManagerCompat
-import androidx.core.graphics.drawable.IconCompat
-import com.android.systemui.R
+import com.android.systemui.notetask.InternalNoteTaskApi
+import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
import javax.inject.Inject
/**
@@ -42,62 +40,16 @@
@Inject
constructor(
private val roleManager: RoleManager,
+ private val shortcutManager: ShortcutManager,
) : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- val intent =
- createShortcutIntent(
- id = SHORTCUT_ID,
- shortLabel = getString(R.string.note_task_button_label),
- intent = LaunchNoteTaskActivity.newIntent(context = this),
- iconResource = R.drawable.ic_note_task_shortcut_widget,
- )
- setResult(Activity.RESULT_OK, intent)
+ val shortcutInfo = roleManager.createNoteShortcutInfoAsUser(context = this, user)
+ val shortcutIntent = shortcutManager.createShortcutResultIntent(shortcutInfo)
+ setResult(Activity.RESULT_OK, shortcutIntent)
finish()
}
-
- private fun createShortcutIntent(
- id: String,
- shortLabel: String,
- intent: Intent,
- @DrawableRes iconResource: Int,
- ): Intent {
- val extras = PersistableBundle()
-
- roleManager.getRoleHoldersAsUser(RoleManager.ROLE_NOTES, user).firstOrNull()?.let { name ->
- extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, name)
- }
-
- val shortcutInfo =
- ShortcutInfoCompat.Builder(this, id)
- .setIntent(intent)
- .setShortLabel(shortLabel)
- .setLongLived(true)
- .setIcon(IconCompat.createWithResource(this, iconResource))
- .setExtras(extras)
- .build()
-
- return ShortcutManagerCompat.createShortcutResultIntent(
- this,
- shortcutInfo,
- )
- }
-
- private companion object {
- private const val SHORTCUT_ID = "note-task-shortcut-id"
-
- /**
- * Shortcut extra which can point to a package name and can be used to indicate an alternate
- * badge info. Launcher only reads this if the shortcut comes from a system app.
- *
- * Duplicated from [com.android.launcher3.icons.IconCache].
- *
- * @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
- */
- private const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE =
- "extra_shortcut_badge_override_package"
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index df1c8df..08fe270 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -18,24 +18,26 @@
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+import android.annotation.Nullable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.UserManager;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
import android.widget.Switch;
-import androidx.annotation.Nullable;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
@@ -50,6 +52,7 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import java.util.List;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -60,8 +63,14 @@
private static final Intent BLUETOOTH_SETTINGS = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
+ private static final String TAG = BluetoothTile.class.getSimpleName();
+
private final BluetoothController mController;
+ private CachedBluetoothDevice mMetadataRegisteredDevice = null;
+
+ private final Executor mExecutor;
+
@Inject
public BluetoothTile(
QSHost host,
@@ -78,6 +87,7 @@
statusBarStateController, activityStarter, qsLogger);
mController = bluetoothController;
mController.observe(getLifecycle(), mCallback);
+ mExecutor = new HandlerExecutor(mainHandler);
}
@Override
@@ -117,6 +127,15 @@
}
@Override
+ protected void handleSetListening(boolean listening) {
+ super.handleSetListening(listening);
+
+ if (!listening) {
+ stopListeningToStaleDeviceMetadata();
+ }
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_BLUETOOTH);
final boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
@@ -125,6 +144,9 @@
final boolean connecting = mController.isBluetoothConnecting();
state.isTransient = transientEnabling || connecting ||
mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
+ if (!enabled || !connected || state.isTransient) {
+ stopListeningToStaleDeviceMetadata();
+ }
state.dualTarget = true;
state.value = enabled;
if (state.slash == null) {
@@ -187,23 +209,32 @@
List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
if (enabled && connected && !connectedDevices.isEmpty()) {
if (connectedDevices.size() > 1) {
+ stopListeningToStaleDeviceMetadata();
return icuMessageFormat(mContext.getResources(),
R.string.quick_settings_hotspot_secondary_label_num_devices,
connectedDevices.size());
}
- CachedBluetoothDevice lastDevice = connectedDevices.get(0);
- final int batteryLevel = lastDevice.getBatteryLevel();
+ CachedBluetoothDevice device = connectedDevices.get(0);
+
+ // Use battery level provided by FastPair metadata if available.
+ // If not, fallback to the default battery level from bluetooth.
+ int batteryLevel = getMetadataBatteryLevel(device);
+ if (batteryLevel > BluetoothUtils.META_INT_ERROR) {
+ listenToMetadata(device);
+ } else {
+ stopListeningToStaleDeviceMetadata();
+ batteryLevel = device.getBatteryLevel();
+ }
if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
return mContext.getString(
R.string.quick_settings_bluetooth_secondary_label_battery_level,
Utils.formatPercentage(batteryLevel));
-
} else {
- final BluetoothClass bluetoothClass = lastDevice.getBtClass();
+ final BluetoothClass bluetoothClass = device.getBtClass();
if (bluetoothClass != null) {
- if (lastDevice.isHearingAidDevice()) {
+ if (device.isHearingAidDevice()) {
return mContext.getString(
R.string.quick_settings_bluetooth_secondary_label_hearing_aids);
} else if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
@@ -233,6 +264,36 @@
return mController.isBluetoothSupported();
}
+ private int getMetadataBatteryLevel(CachedBluetoothDevice device) {
+ return BluetoothUtils.getIntMetaData(device.getDevice(),
+ BluetoothDevice.METADATA_MAIN_BATTERY);
+ }
+
+ private void listenToMetadata(CachedBluetoothDevice cachedDevice) {
+ if (cachedDevice == mMetadataRegisteredDevice) return;
+ stopListeningToStaleDeviceMetadata();
+ try {
+ mController.addOnMetadataChangedListener(cachedDevice,
+ mExecutor,
+ mMetadataChangedListener);
+ mMetadataRegisteredDevice = cachedDevice;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Battery metadata listener already registered for device.");
+ }
+ }
+
+ private void stopListeningToStaleDeviceMetadata() {
+ if (mMetadataRegisteredDevice == null) return;
+ try {
+ mController.removeOnMetadataChangedListener(
+ mMetadataRegisteredDevice,
+ mMetadataChangedListener);
+ mMetadataRegisteredDevice = null;
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Battery metadata listener already unregistered for device.");
+ }
+ }
+
private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
@Override
public void onBluetoothStateChange(boolean enabled) {
@@ -244,4 +305,9 @@
refreshState();
}
};
+
+ private final BluetoothAdapter.OnMetadataChangedListener mMetadataChangedListener =
+ (device, key, value) -> {
+ if (key == BluetoothDevice.METADATA_MAIN_BATTERY) refreshState();
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index aa2ea0b6..75d0172 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -35,6 +35,7 @@
import androidx.annotation.Nullable;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.graph.SignalDrawable;
@@ -174,6 +175,15 @@
@Nullable
String mEthernetContentDescription;
+ public void copyTo(EthernetCallbackInfo ethernetCallbackInfo) {
+ if (ethernetCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ ethernetCallbackInfo.mConnected = this.mConnected;
+ ethernetCallbackInfo.mEthernetSignalIconId = this.mEthernetSignalIconId;
+ ethernetCallbackInfo.mEthernetContentDescription = this.mEthernetContentDescription;
+ }
+
@Override
public String toString() {
return new StringBuilder("EthernetCallbackInfo[")
@@ -200,6 +210,23 @@
boolean mNoValidatedNetwork;
boolean mNoNetworksAvailable;
+ public void copyTo(WifiCallbackInfo wifiCallbackInfo) {
+ if (wifiCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ wifiCallbackInfo.mAirplaneModeEnabled = this.mAirplaneModeEnabled;
+ wifiCallbackInfo.mEnabled = this.mEnabled;
+ wifiCallbackInfo.mConnected = this.mConnected;
+ wifiCallbackInfo.mWifiSignalIconId = this.mWifiSignalIconId;
+ wifiCallbackInfo.mSsid = this.mSsid;
+ wifiCallbackInfo.mWifiSignalContentDescription = this.mWifiSignalContentDescription;
+ wifiCallbackInfo.mIsTransient = this.mIsTransient;
+ wifiCallbackInfo.mStatusLabel = this.mStatusLabel;
+ wifiCallbackInfo.mNoDefaultNetwork = this.mNoDefaultNetwork;
+ wifiCallbackInfo.mNoValidatedNetwork = this.mNoValidatedNetwork;
+ wifiCallbackInfo.mNoNetworksAvailable = this.mNoNetworksAvailable;
+ }
+
@Override
public String toString() {
return new StringBuilder("WifiCallbackInfo[")
@@ -232,6 +259,23 @@
boolean mNoValidatedNetwork;
boolean mNoNetworksAvailable;
+ public void copyTo(CellularCallbackInfo cellularCallbackInfo) {
+ if (cellularCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ cellularCallbackInfo.mAirplaneModeEnabled = this.mAirplaneModeEnabled;
+ cellularCallbackInfo.mDataSubscriptionName = this.mDataSubscriptionName;
+ cellularCallbackInfo.mDataContentDescription = this.mDataContentDescription;
+ cellularCallbackInfo.mMobileSignalIconId = this.mMobileSignalIconId;
+ cellularCallbackInfo.mQsTypeIcon = this.mQsTypeIcon;
+ cellularCallbackInfo.mNoSim = this.mNoSim;
+ cellularCallbackInfo.mRoaming = this.mRoaming;
+ cellularCallbackInfo.mMultipleSubs = this.mMultipleSubs;
+ cellularCallbackInfo.mNoDefaultNetwork = this.mNoDefaultNetwork;
+ cellularCallbackInfo.mNoValidatedNetwork = this.mNoValidatedNetwork;
+ cellularCallbackInfo.mNoNetworksAvailable = this.mNoNetworksAvailable;
+ }
+
@Override
public String toString() {
return new StringBuilder("CellularCallbackInfo[")
@@ -251,8 +295,11 @@
}
protected final class InternetSignalCallback implements SignalCallback {
+ @GuardedBy("mWifiInfo")
final WifiCallbackInfo mWifiInfo = new WifiCallbackInfo();
+ @GuardedBy("mCellularInfo")
final CellularCallbackInfo mCellularInfo = new CellularCallbackInfo();
+ @GuardedBy("mEthernetInfo")
final EthernetCallbackInfo mEthernetInfo = new EthernetCallbackInfo();
@@ -261,19 +308,23 @@
if (DEBUG) {
Log.d(TAG, "setWifiIndicators: " + indicators);
}
- mWifiInfo.mEnabled = indicators.enabled;
- mWifiInfo.mSsid = indicators.description;
- mWifiInfo.mIsTransient = indicators.isTransient;
- mWifiInfo.mStatusLabel = indicators.statusLabel;
+ synchronized (mWifiInfo) {
+ mWifiInfo.mEnabled = indicators.enabled;
+ mWifiInfo.mSsid = indicators.description;
+ mWifiInfo.mIsTransient = indicators.isTransient;
+ mWifiInfo.mStatusLabel = indicators.statusLabel;
+ if (indicators.qsIcon != null) {
+ mWifiInfo.mConnected = indicators.qsIcon.visible;
+ mWifiInfo.mWifiSignalIconId = indicators.qsIcon.icon;
+ mWifiInfo.mWifiSignalContentDescription = indicators.qsIcon.contentDescription;
+ } else {
+ mWifiInfo.mConnected = false;
+ mWifiInfo.mWifiSignalIconId = 0;
+ mWifiInfo.mWifiSignalContentDescription = null;
+ }
+ }
if (indicators.qsIcon != null) {
- mWifiInfo.mConnected = indicators.qsIcon.visible;
- mWifiInfo.mWifiSignalIconId = indicators.qsIcon.icon;
- mWifiInfo.mWifiSignalContentDescription = indicators.qsIcon.contentDescription;
refreshState(mWifiInfo);
- } else {
- mWifiInfo.mConnected = false;
- mWifiInfo.mWifiSignalIconId = 0;
- mWifiInfo.mWifiSignalContentDescription = null;
}
}
@@ -286,14 +337,16 @@
// Not data sim, don't display.
return;
}
- mCellularInfo.mDataSubscriptionName = indicators.qsDescription == null
+ synchronized (mCellularInfo) {
+ mCellularInfo.mDataSubscriptionName = indicators.qsDescription == null
? mController.getMobileDataNetworkName() : indicators.qsDescription;
- mCellularInfo.mDataContentDescription = indicators.qsDescription != null
+ mCellularInfo.mDataContentDescription = indicators.qsDescription != null
? indicators.typeContentDescriptionHtml : null;
- mCellularInfo.mMobileSignalIconId = indicators.qsIcon.icon;
- mCellularInfo.mQsTypeIcon = indicators.qsType;
- mCellularInfo.mRoaming = indicators.roaming;
- mCellularInfo.mMultipleSubs = mController.getNumberSubscriptions() > 1;
+ mCellularInfo.mMobileSignalIconId = indicators.qsIcon.icon;
+ mCellularInfo.mQsTypeIcon = indicators.qsType;
+ mCellularInfo.mRoaming = indicators.roaming;
+ mCellularInfo.mMultipleSubs = mController.getNumberSubscriptions() > 1;
+ }
refreshState(mCellularInfo);
}
@@ -303,9 +356,11 @@
Log.d(TAG, "setEthernetIndicators: "
+ "icon = " + (icon == null ? "" : icon.toString()));
}
- mEthernetInfo.mConnected = icon.visible;
- mEthernetInfo.mEthernetSignalIconId = icon.icon;
- mEthernetInfo.mEthernetContentDescription = icon.contentDescription;
+ synchronized (mEthernetInfo) {
+ mEthernetInfo.mConnected = icon.visible;
+ mEthernetInfo.mEthernetSignalIconId = icon.icon;
+ mEthernetInfo.mEthernetContentDescription = icon.contentDescription;
+ }
if (icon.visible) {
refreshState(mEthernetInfo);
}
@@ -318,11 +373,13 @@
+ "show = " + show + ","
+ "simDetected = " + simDetected);
}
- mCellularInfo.mNoSim = show;
- if (mCellularInfo.mNoSim) {
- // Make sure signal gets cleared out when no sims.
- mCellularInfo.mMobileSignalIconId = 0;
- mCellularInfo.mQsTypeIcon = 0;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mNoSim = show;
+ if (mCellularInfo.mNoSim) {
+ // Make sure signal gets cleared out when no sims.
+ mCellularInfo.mMobileSignalIconId = 0;
+ mCellularInfo.mQsTypeIcon = 0;
+ }
}
}
@@ -335,8 +392,12 @@
if (mCellularInfo.mAirplaneModeEnabled == icon.visible) {
return;
}
- mCellularInfo.mAirplaneModeEnabled = icon.visible;
- mWifiInfo.mAirplaneModeEnabled = icon.visible;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mAirplaneModeEnabled = icon.visible;
+ }
+ synchronized (mWifiInfo) {
+ mWifiInfo.mAirplaneModeEnabled = icon.visible;
+ }
if (!mSignalCallback.mEthernetInfo.mConnected) {
// Always use mWifiInfo to refresh the Internet Tile if airplane mode is enabled,
// because Internet Tile will show different information depending on whether WiFi
@@ -363,12 +424,16 @@
+ "noValidatedNetwork = " + noValidatedNetwork + ","
+ "noNetworksAvailable = " + noNetworksAvailable);
}
- mCellularInfo.mNoDefaultNetwork = noDefaultNetwork;
- mCellularInfo.mNoValidatedNetwork = noValidatedNetwork;
- mCellularInfo.mNoNetworksAvailable = noNetworksAvailable;
- mWifiInfo.mNoDefaultNetwork = noDefaultNetwork;
- mWifiInfo.mNoValidatedNetwork = noValidatedNetwork;
- mWifiInfo.mNoNetworksAvailable = noNetworksAvailable;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mNoDefaultNetwork = noDefaultNetwork;
+ mCellularInfo.mNoValidatedNetwork = noValidatedNetwork;
+ mCellularInfo.mNoNetworksAvailable = noNetworksAvailable;
+ }
+ synchronized (mWifiInfo) {
+ mWifiInfo.mNoDefaultNetwork = noDefaultNetwork;
+ mWifiInfo.mNoValidatedNetwork = noValidatedNetwork;
+ mWifiInfo.mNoNetworksAvailable = noNetworksAvailable;
+ }
if (!noDefaultNetwork) {
return;
}
@@ -403,11 +468,23 @@
// arg = null, in this case the last updated CellularCallbackInfo or WifiCallbackInfo
// should be used to refresh the tile.
if (mLastTileState == LAST_STATE_CELLULAR) {
- handleUpdateCellularState(state, mSignalCallback.mCellularInfo);
+ CellularCallbackInfo cellularInfo = new CellularCallbackInfo();
+ synchronized (mSignalCallback.mCellularInfo) {
+ mSignalCallback.mCellularInfo.copyTo(cellularInfo);
+ }
+ handleUpdateCellularState(state, cellularInfo);
} else if (mLastTileState == LAST_STATE_WIFI) {
- handleUpdateWifiState(state, mSignalCallback.mWifiInfo);
+ WifiCallbackInfo mifiInfo = new WifiCallbackInfo();
+ synchronized (mSignalCallback.mWifiInfo) {
+ mSignalCallback.mWifiInfo.copyTo(mifiInfo);
+ }
+ handleUpdateWifiState(state, mifiInfo);
} else if (mLastTileState == LAST_STATE_ETHERNET) {
- handleUpdateEthernetState(state, mSignalCallback.mEthernetInfo);
+ EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
+ synchronized (mSignalCallback.mEthernetInfo) {
+ mSignalCallback.mEthernetInfo.copyTo(ethernetInfo);
+ }
+ handleUpdateEthernetState(state, ethernetInfo);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 0748bcb..c28a40a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -140,7 +140,8 @@
private final Handler mHandler;
private final Lazy<NavigationBarController> mNavBarControllerLazy;
private final NotificationShadeWindowController mStatusBarWinController;
- private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
+ private final Runnable mConnectionRunnable = () ->
+ internalConnectToCurrentUser("runnable: startConnectionToCurrentUser");
private final ComponentName mRecentsComponentName;
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
private final Intent mQuickStepIntent;
@@ -406,7 +407,7 @@
// Failed to link to death (process may have died between binding and connecting),
// just unbind the service for now and retry again
Log.e(TAG_OPS, "Lost connection to launcher service", e);
- disconnectFromLauncherService();
+ disconnectFromLauncherService("Lost connection to launcher service");
retryConnectionWithBackoff();
return;
}
@@ -501,7 +502,7 @@
@Override
public void onUserChanged(int newUser, @NonNull Context userContext) {
mConnectionBackoffAttempts = 0;
- internalConnectToCurrentUser();
+ internalConnectToCurrentUser("User changed");
}
};
@@ -716,12 +717,12 @@
if (mHandler.getLooper() != Looper.myLooper()) {
mHandler.post(mConnectionRunnable);
} else {
- internalConnectToCurrentUser();
+ internalConnectToCurrentUser("startConnectionToCurrentUser");
}
}
- private void internalConnectToCurrentUser() {
- disconnectFromLauncherService();
+ private void internalConnectToCurrentUser(String reason) {
+ disconnectFromLauncherService(reason);
// If user has not setup yet or already connected, do not try to connect
if (!isEnabled()) {
@@ -783,7 +784,9 @@
return mOverviewProxy;
}
- private void disconnectFromLauncherService() {
+ private void disconnectFromLauncherService(String disconnectReason) {
+ Log.d(TAG_OPS, "disconnectFromLauncherService bound?: " + mBound +
+ " currentProxy: " + mOverviewProxy + " disconnectReason: " + disconnectReason);
if (mBound) {
// Always unbind the service (ie. if called through onNullBinding or onBindingDied)
mContext.unbindService(mOverviewServiceConnection);
@@ -1047,6 +1050,6 @@
mContext.unregisterReceiver(mLauncherStateChangedReceiver);
mIsEnabled = false;
mHandler.removeCallbacks(mConnectionRunnable);
- disconnectFromLauncherService();
+ disconnectFromLauncherService("Shutdown for test");
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
index 48aa60f..253f07d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
@@ -17,6 +17,8 @@
package com.android.systemui.screenshot
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ComponentInfoFlags
+import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.view.Display
import android.view.IWindowManager
import android.view.ViewGroup
@@ -45,7 +47,7 @@
// Convert component names to app names.
return components.map {
packageManager
- .getActivityInfo(it, PackageManager.ComponentInfoFlags.of(0))
+ .getActivityInfo(it, ComponentInfoFlags.of(MATCH_DISABLED_COMPONENTS.toLong()))
.loadLabel(packageManager)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
index 236213c..798c490 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
@@ -19,6 +19,7 @@
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ComponentInfoFlags
import android.graphics.drawable.Drawable
import android.os.UserHandle
import android.os.UserManager
@@ -53,12 +54,9 @@
var badgedIcon: Drawable? = null
var label: CharSequence? = null
val fileManager = fileManagerComponentName()
+ ?: return WorkProfileFirstRunData(defaultFileAppName(), null)
try {
- val info =
- packageManager.getActivityInfo(
- fileManager,
- PackageManager.ComponentInfoFlags.of(0)
- )
+ val info = packageManager.getActivityInfo(fileManager, ComponentInfoFlags.of(0L))
val icon = packageManager.getActivityIcon(fileManager)
badgedIcon = packageManager.getUserBadgedIcon(icon, userHandle)
label = info.loadLabel(packageManager)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 3360511..fbcc9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -979,6 +979,7 @@
onTrackingStopped(false);
instantCollapse();
} else {
+ mView.animate().cancel();
mView.animate()
.alpha(0f)
.setStartDelay(0)
@@ -2805,7 +2806,6 @@
public void setIsLaunchAnimationRunning(boolean running) {
boolean wasRunning = mIsLaunchAnimationRunning;
mIsLaunchAnimationRunning = running;
- mCentralSurfaces.updateIsKeyguard();
if (wasRunning != mIsLaunchAnimationRunning) {
mShadeExpansionStateManager.notifyLaunchingActivityChanged(running);
}
@@ -3149,7 +3149,9 @@
*/
public void startFoldToAodAnimation(Runnable startAction, Runnable endAction,
Runnable cancelAction) {
- mView.animate()
+ final ViewPropertyAnimator viewAnimator = mView.animate();
+ viewAnimator.cancel();
+ viewAnimator
.translationX(0)
.alpha(1f)
.setDuration(ANIMATION_DURATION_FOLD_TO_AOD)
@@ -3168,9 +3170,14 @@
@Override
public void onAnimationEnd(Animator animation) {
endAction.run();
+
+ viewAnimator.setListener(null);
+ viewAnimator.setUpdateListener(null);
}
- }).setUpdateListener(anim -> mKeyguardStatusViewController.animateFoldToAod(
- anim.getAnimatedFraction())).start();
+ })
+ .setUpdateListener(anim ->
+ mKeyguardStatusViewController.animateFoldToAod(anim.getAnimatedFraction()))
+ .start();
}
/** Cancels fold to AOD transition and resets view state. */
@@ -3369,6 +3376,7 @@
}
public ViewPropertyAnimator fadeOut(long startDelayMs, long durationMs, Runnable endAction) {
+ mView.animate().cancel();
return mView.animate().alpha(0).setStartDelay(startDelayMs).setDuration(
durationMs).setInterpolator(Interpolators.ALPHA_OUT).withLayer().withEndAction(
endAction);
@@ -3858,10 +3866,6 @@
return mClosing || mIsLaunchAnimationRunning;
}
- public boolean isLaunchAnimationRunning() {
- return mIsLaunchAnimationRunning;
- }
-
public boolean isTracking() {
return mTracking;
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index e7759df..156e4fd 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -301,11 +301,9 @@
}
private void applyKeyguardFlags(NotificationShadeWindowState state) {
- // Keyguard is visible if it's showing or if it's fading away (in which case we're animating
- // it out, but the wallpaper should remain visible as a backdrop for the animation);
- final boolean keyguardOrAodVisible = (state.keyguardShowing || state.keyguardFadingAway)
+ final boolean keyguardOrAod = state.keyguardShowing
|| (state.dozing && mDozeParameters.getAlwaysOn());
- if ((keyguardOrAodVisible && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque)
+ if ((keyguardOrAod && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque)
|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) {
// Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
// solid backdrop. Also, show it if we are currently animating between the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 5adb58b..63179da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -77,12 +77,6 @@
*/
public static void fadeOut(View view, float fadeOutAmount, boolean remap) {
view.animate().cancel();
-
- // Don't fade out if already not visible.
- if (view.getAlpha() == 0.0f) {
- return;
- }
-
if (fadeOutAmount == 1.0f && view.getVisibility() != View.GONE) {
view.setVisibility(View.INVISIBLE);
} else if (view.getVisibility() == View.INVISIBLE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 779be2b..fda2277 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -28,7 +28,6 @@
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
-import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
@@ -99,6 +98,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.log.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -146,6 +146,7 @@
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final AuthController mAuthController;
private final KeyguardLogger mKeyguardLogger;
+ private final UserTracker mUserTracker;
private ViewGroup mIndicationArea;
private KeyguardIndicationTextView mTopIndicationView;
private KeyguardIndicationTextView mLockScreenIndicationView;
@@ -251,7 +252,8 @@
FaceHelpMessageDeferral faceHelpMessageDeferral,
KeyguardLogger keyguardLogger,
AlternateBouncerInteractor alternateBouncerInteractor,
- AlarmManager alarmManager
+ AlarmManager alarmManager,
+ UserTracker userTracker
) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
@@ -275,6 +277,7 @@
mKeyguardLogger = keyguardLogger;
mScreenLifecycle.addObserver(mScreenObserver);
mAlternateBouncerInteractor = alternateBouncerInteractor;
+ mUserTracker = userTracker;
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
@@ -475,6 +478,10 @@
}
}
+ private int getCurrentUser() {
+ return mUserTracker.getUserId();
+ }
+
private void updateLockScreenOwnerInfo() {
// Check device owner info on a bg thread.
// It makes multiple IPCs that could block the thread it's run on.
@@ -1166,8 +1173,7 @@
mContext.getString(R.string.keyguard_unlock)
);
} else if (fpAuthFailed
- && mKeyguardUpdateMonitor.getUserHasTrust(
- KeyguardUpdateMonitor.getCurrentUser())) {
+ && mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser())) {
showBiometricMessage(
getTrustGrantedIndication(),
mContext.getString(R.string.keyguard_unlock)
@@ -1421,7 +1427,7 @@
private boolean canUnlockWithFingerprint() {
return mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- KeyguardUpdateMonitor.getCurrentUser());
+ getCurrentUser());
}
private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index bc531da..3399f9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -71,6 +71,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.stack.PriorityBucket;
+import com.android.systemui.util.ListenerSet;
import java.util.ArrayList;
import java.util.List;
@@ -163,7 +164,8 @@
private boolean hasSentReply;
private boolean mSensitive = true;
- private List<OnSensitivityChangedListener> mOnSensitivityChangedListeners = new ArrayList<>();
+ private ListenerSet<OnSensitivityChangedListener> mOnSensitivityChangedListeners =
+ new ListenerSet<>();
private boolean mAutoHeadsUp;
private boolean mPulseSupressed;
@@ -932,8 +934,9 @@
getRow().setSensitive(sensitive, deviceSensitive);
if (sensitive != mSensitive) {
mSensitive = sensitive;
- for (int i = 0; i < mOnSensitivityChangedListeners.size(); i++) {
- mOnSensitivityChangedListeners.get(i).onSensitivityChanged(this);
+ for (NotificationEntry.OnSensitivityChangedListener listener :
+ mOnSensitivityChangedListeners) {
+ listener.onSensitivityChanged(this);
}
}
}
@@ -944,7 +947,7 @@
/** Add a listener to be notified when the entry's sensitivity changes. */
public void addOnSensitivityChangedListener(OnSensitivityChangedListener listener) {
- mOnSensitivityChangedListeners.add(listener);
+ mOnSensitivityChangedListeners.addIfAbsent(listener);
}
/** Remove a listener that was registered above. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 4065b98..0205523 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -110,6 +110,8 @@
private final PipelineState mPipelineState = new PipelineState();
private final Map<String, GroupEntry> mGroups = new ArrayMap<>();
private Collection<NotificationEntry> mAllEntries = Collections.emptyList();
+ @Nullable
+ private Collection<NotificationEntry> mPendingEntries = null;
private int mIterationCount = 0;
private final List<NotifFilter> mNotifPreGroupFilters = new ArrayList<>();
@@ -317,11 +319,9 @@
@Override
public void onBuildList(Collection<NotificationEntry> entries, String reason) {
Assert.isMainThread();
- mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
-
+ mPendingEntries = new ArrayList<>(entries);
mLogger.logOnBuildList(reason);
- mAllEntries = entries;
- scheduleRebuild(/* reentrant = */ false);
+ rebuildListIfBefore(STATE_BUILD_STARTED);
}
};
@@ -398,6 +398,11 @@
Trace.beginSection("ShadeListBuilder.buildList");
mPipelineState.requireIsBefore(STATE_BUILD_STARTED);
+ if (mPendingEntries != null) {
+ mAllEntries = mPendingEntries;
+ mPendingEntries = null;
+ }
+
if (!mNotifStabilityManager.isPipelineRunAllowed()) {
mLogger.logPipelineRunSuppressed();
Trace.endSection();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index d2db622..6500ff7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -359,7 +359,8 @@
}
NotifInflater.Params getInflaterParams(NotifUiAdjustment adjustment, String reason) {
- return new NotifInflater.Params(adjustment.isMinimized(), reason);
+ return new NotifInflater.Params(adjustment.isMinimized(), reason,
+ adjustment.isSnoozeEnabled());
}
private void abortInflation(NotificationEntry entry, String reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
index 08e21e8..4483599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
@@ -61,5 +61,5 @@
/**
* A class holding parameters used when inflating the notification row
*/
- class Params(val isLowPriority: Boolean, val reason: String)
+ class Params(val isLowPriority: Boolean, val reason: String, val showSnooze: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
index 745d6fe..0d9a654 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
@@ -16,12 +16,15 @@
package com.android.systemui.statusbar.notification.collection.inflation
+import android.content.Context
import android.database.ContentObserver
import android.os.Handler
+import android.os.HandlerExecutor
import android.os.UserHandle
import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -39,11 +42,25 @@
@Main private val handler: Handler,
private val secureSettings: SecureSettings,
private val lockscreenUserManager: NotificationLockscreenUserManager,
- private val sectionStyleProvider: SectionStyleProvider
+ private val sectionStyleProvider: SectionStyleProvider,
+ private val userTracker: UserTracker
) {
private val dirtyListeners = ListenerSet<Runnable>()
private var isSnoozeEnabled = false
+ /**
+ * Update the snooze enabled value on user switch
+ */
+ private val userTrackerCallback = object : UserTracker.Callback {
+ override fun onUserChanged(newUser: Int, userContext: Context) {
+ updateSnoozeEnabled()
+ }
+ }
+
+ init {
+ userTracker.addCallback(userTrackerCallback, HandlerExecutor(handler))
+ }
+
fun addDirtyListener(listener: Runnable) {
if (dirtyListeners.isEmpty()) {
lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener)
@@ -78,7 +95,8 @@
}
private fun updateSnoozeEnabled() {
- isSnoozeEnabled = secureSettings.getInt(SHOW_NOTIFICATION_SNOOZE, 0) == 1
+ isSnoozeEnabled =
+ secureSettings.getIntForUser(SHOW_NOTIFICATION_SNOOZE, 0, UserHandle.USER_CURRENT) == 1
}
private fun isEntryMinimized(entry: NotificationEntry): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 56eb4b1..611edf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -212,6 +212,9 @@
mMessagingUtil.isImportantMessaging(entry.getSbn(), entry.getImportance());
final boolean isLowPriority = inflaterParams.isLowPriority();
+ // Set show snooze action
+ row.setShowSnooze(inflaterParams.getShowSnooze());
+
RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED);
params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
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 a529da5..a9d1255 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
@@ -47,7 +47,6 @@
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
-import android.util.Property;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -147,6 +146,7 @@
// the background on first content update just in case it happens to be during a theme change.
private boolean mUpdateSelfBackgroundOnUpdate = true;
private boolean mIsSnoozed;
+ private boolean mShowSnooze = false;
private boolean mIsFaded;
private boolean mAnimatePinnedRoundness = false;
@@ -336,8 +336,8 @@
};
private boolean mKeepInParentForDismissAnimation;
private boolean mRemoved;
- private static final Property<ExpandableNotificationRow, Float> TRANSLATE_CONTENT =
- new FloatProperty<ExpandableNotificationRow>("translate") {
+ public static final FloatProperty<ExpandableNotificationRow> TRANSLATE_CONTENT =
+ new FloatProperty<>("translate") {
@Override
public void setValue(ExpandableNotificationRow object, float value) {
object.setTranslation(value);
@@ -348,6 +348,7 @@
return object.getTranslation();
}
};
+
private OnClickListener mOnClickListener;
private OnDragSuccessListener mOnDragSuccessListener;
private boolean mHeadsupDisappearRunning;
@@ -2177,6 +2178,13 @@
return translateAnim;
}
+ /** Cancels the ongoing translate animation if there is any. */
+ public void cancelTranslateAnimation() {
+ if (mTranslateAnim != null) {
+ mTranslateAnim.cancel();
+ }
+ }
+
void ensureGutsInflated() {
if (mGuts == null) {
mGutsStub.inflate();
@@ -3728,4 +3736,14 @@
updateBaseRoundness();
}
}
+
+ /** Set whether this notification may show a snooze action. */
+ public void setShowSnooze(boolean showSnooze) {
+ mShowSnooze = showSnooze;
+ }
+
+ /** Whether this notification may show a snooze action. */
+ public boolean getShowSnooze() {
+ return mShowSnooze;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 78392f7..451d837 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -26,7 +26,6 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.RemoteException;
-import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.AttributeSet;
@@ -1440,11 +1439,9 @@
if (snoozeButton == null || actionContainer == null) {
return;
}
- final boolean showSnooze = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1;
// Notification.Builder can 'disable' the snooze button to prevent it from being shown here
boolean snoozeDisabled = !snoozeButton.isEnabled();
- if (!showSnooze || snoozeDisabled) {
+ if (!mContainingNotification.getShowSnooze() || snoozeDisabled) {
snoozeButton.setVisibility(GONE);
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d0fb416..bafc474 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.notification.row;
-import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
@@ -253,9 +252,7 @@
mLeftMenuItems.clear();
mRightMenuItems.clear();
- boolean showSnooze = Settings.Secure.getInt(mContext.getContentResolver(),
- SHOW_NOTIFICATION_SNOOZE, 0) == 1;
-
+ final boolean showSnooze = mParent.getShowSnooze();
// Construct the menu items based on the notification
if (showSnooze) {
// Only show snooze for non-foreground notifications, and if the setting is on
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 c0aed7a..a2de3c3 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
@@ -200,6 +200,7 @@
private final boolean mDebugRemoveAnimation;
private final boolean mSimplifiedAppearFraction;
private final boolean mUseRoundnessSourceTypes;
+ private final boolean mSensitiveRevealAnimEndabled;
private boolean mAnimatedInsets;
private int mContentHeight;
@@ -580,6 +581,18 @@
}
};
+ private final NotificationEntry.OnSensitivityChangedListener
+ mOnChildSensitivityChangedListener =
+ new NotificationEntry.OnSensitivityChangedListener() {
+ @Override
+ public void onSensitivityChanged(NotificationEntry entry) {
+ if (mAnimationsEnabled) {
+ mHideSensitiveNeedsAnimation = true;
+ requestChildrenUpdate();
+ }
+ }
+ };
+
private Consumer<Integer> mScrollListener;
private final ScrollAdapter mScrollAdapter = new ScrollAdapter() {
@Override
@@ -611,6 +624,7 @@
mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
mSimplifiedAppearFraction = featureFlags.isEnabled(Flags.SIMPLIFIED_APPEAR_FRACTION);
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
+ mSensitiveRevealAnimEndabled = featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM);
setAnimatedInsetsEnabled(featureFlags.isEnabled(Flags.ANIMATED_NOTIFICATION_SHADE_INSETS));
mSectionsManager = Dependency.get(NotificationSectionsManager.class);
mScreenOffAnimationController =
@@ -2860,6 +2874,10 @@
return;
}
child.setOnHeightChangedListener(null);
+ if (child instanceof ExpandableNotificationRow && mSensitiveRevealAnimEndabled) {
+ NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
+ entry.removeOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
+ }
updateScrollStateForRemovedChild(child);
boolean animationGenerated = container != null && generateRemoveAnimation(child);
if (animationGenerated) {
@@ -3121,6 +3139,10 @@
private void onViewAddedInternal(ExpandableView child) {
updateHideSensitiveForChild(child);
child.setOnHeightChangedListener(mOnChildHeightChangedListener);
+ if (child instanceof ExpandableNotificationRow && mSensitiveRevealAnimEndabled) {
+ NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
+ entry.addOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
+ }
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
updateChronometerForChild(child);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index c6f56d4..b476b68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -135,11 +135,15 @@
@Override
protected void onChildSnappedBack(View animView, float targetLeft) {
+ super.onChildSnappedBack(animView, targetLeft);
+
final NotificationMenuRowPlugin menuRow = getCurrentMenuRow();
if (menuRow != null && targetLeft == 0) {
menuRow.resetMenu();
clearCurrentMenuRow();
}
+
+ InteractionJankMonitor.getInstance().end(CUJ_NOTIFICATION_SHADE_ROW_SWIPE);
}
@Override
@@ -348,18 +352,13 @@
super.dismissChild(view, velocity, useAccelerateInterpolator);
}
- @Override
- protected void onSnapChildWithAnimationFinished() {
- InteractionJankMonitor.getInstance().end(CUJ_NOTIFICATION_SHADE_ROW_SWIPE);
- }
-
@VisibleForTesting
protected void superSnapChild(final View animView, final float targetLeft, float velocity) {
super.snapChild(animView, targetLeft, velocity);
}
@Override
- public void snapChild(final View animView, final float targetLeft, float velocity) {
+ protected void snapChild(final View animView, final float targetLeft, float velocity) {
superSnapChild(animView, targetLeft, velocity);
mCallback.onDragCancelled(animView);
if (targetLeft == 0) {
@@ -380,20 +379,18 @@
}
}
+ @Override
@VisibleForTesting
- protected Animator superGetViewTranslationAnimator(View v, float target,
+ protected Animator getViewTranslationAnimator(View view, float target,
ValueAnimator.AnimatorUpdateListener listener) {
- return super.getViewTranslationAnimator(v, target, listener);
+ return super.getViewTranslationAnimator(view, target, listener);
}
@Override
- public Animator getViewTranslationAnimator(View v, float target,
+ @VisibleForTesting
+ protected Animator createTranslationAnimation(View view, float newPos,
ValueAnimator.AnimatorUpdateListener listener) {
- if (v instanceof ExpandableNotificationRow) {
- return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener);
- } else {
- return superGetViewTranslationAnimator(v, target, listener);
- }
+ return super.createTranslationAnimation(view, newPos, listener);
}
@Override
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 2f40487..7f13bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -864,6 +864,7 @@
mStatusBarSignalPolicy = statusBarSignalPolicy;
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
mFeatureFlags = featureFlags;
+ mIsShortcutListSearchEnabled = featureFlags.isEnabled(Flags.SHORTCUT_LIST_SEARCH_LAYOUT);
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mMainExecutor = delayableExecutor;
mMessageRouter = messageRouter;
@@ -872,7 +873,6 @@
mCameraLauncherLazy = cameraLauncherLazy;
mAlternateBouncerInteractor = alternateBouncerInteractor;
mUserTracker = userTracker;
- mIsShortcutListSearchEnabled = featureFlags.isEnabled(Flags.SHORTCUT_LIST_SEARCH_LAYOUT);
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
mStartingSurfaceOptional = startingSurfaceOptional;
@@ -1052,8 +1052,6 @@
// 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()) {
- updateIsKeyguard();
-
if (mLightRevealScrim.getRevealAmount() != 1f) {
Log.e(TAG, "Keyguard is done going away, but someone left the light reveal "
+ "scrim at reveal amount: " + mLightRevealScrim.getRevealAmount());
@@ -2940,10 +2938,6 @@
showKeyguardImpl();
}
} else {
- final boolean isLaunchingOrGoingAway =
- mNotificationPanelViewController.isLaunchAnimationRunning()
- || mKeyguardStateController.isKeyguardGoingAway();
-
// During folding a foldable device this might be called as a result of
// 'onScreenTurnedOff' call for the inner display.
// In this case:
@@ -2955,14 +2949,7 @@
if (!mScreenOffAnimationController.isKeyguardHideDelayed()
// If we're animating occluded, there's an activity launching over the keyguard
// UI. Wait to hide it until after the animation concludes.
- && !mKeyguardViewMediator.isOccludeAnimationPlaying()
- // If we're occluded, but playing an animation (launch or going away animations)
- // the keyguard is visible behind the animation.
- && !(mKeyguardStateController.isOccluded() && isLaunchingOrGoingAway)) {
- // If we're going away and occluded, it means we are launching over the
- // unsecured keyguard, which will subsequently go away. Wait to hide it until
- // after the animation concludes to avoid the lockscreen UI changing into the
- // shade UI behind the launch animation.
+ && !mKeyguardViewMediator.isOccludeAnimationPlaying()) {
return hideKeyguardImpl(forceStateChange);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index f866d65..d0c6215 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -105,10 +105,14 @@
* The reason we need to do this is because TelephonyManager limits the number of registered
* listeners per-process, so we don't want to create a new listener for every callback.
*
- * A note on the design for back pressure here: We use the [coalesce] operator here to change
- * the backpressure strategy to store exactly the last callback event of _each type_ here, as
- * opposed to the default strategy which is to drop the oldest event (regardless of type). This
- * means that we should never miss any single event as long as the flow has been started.
+ * A note on the design for back pressure here: We don't control _which_ telephony callback
+ * comes in first, since we register every relevant bit of information as a batch. E.g., if a
+ * downstream starts collecting on a field which is backed by
+ * [TelephonyCallback.ServiceStateListener], it's not possible for us to guarantee that _that_
+ * callback comes in -- the first callback could very well be
+ * [TelephonyCallback.DataActivityListener], which would promptly be dropped if we didn't keep
+ * it tracked. We use the [scan] operator here to track the most recent callback of _each type_
+ * here. See [TelephonyCallbackState] to see how the callbacks are stored.
*/
private val callbackEvents: StateFlow<TelephonyCallbackState> = run {
val initial = TelephonyCallbackState()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapter.kt
index 5223760..174298a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/WifiUiAdapter.kt
@@ -26,6 +26,7 @@
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel.Companion.viewModelForLocation
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.collect
@@ -60,11 +61,7 @@
location: StatusBarLocation,
): LocationBasedWifiViewModel {
val locationViewModel =
- when (location) {
- StatusBarLocation.HOME -> wifiViewModel.home
- StatusBarLocation.KEYGUARD -> wifiViewModel.keyguard
- StatusBarLocation.QS -> wifiViewModel.qs
- }
+ viewModelForLocation(wifiViewModel, statusBarPipelineFlags, location)
statusBarIconGroup.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt
deleted file mode 100644
index a29c9b9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
-
-import android.graphics.Color
-import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
-import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
-
-/**
- * A view model for the wifi icon shown on the "home" page (aka, when the device is unlocked and not
- * showing the shade, so the user is on the home-screen, or in an app).
- */
-class HomeWifiViewModel(
- statusBarPipelineFlags: StatusBarPipelineFlags,
- wifiIcon: StateFlow<WifiIcon>,
- isActivityInViewVisible: Flow<Boolean>,
- isActivityOutViewVisible: Flow<Boolean>,
- isActivityContainerVisible: Flow<Boolean>,
- isAirplaneSpacerVisible: Flow<Boolean>,
-) :
- LocationBasedWifiViewModel(
- statusBarPipelineFlags,
- debugTint = Color.CYAN,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt
deleted file mode 100644
index 1e190fb..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
-
-import android.graphics.Color
-import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
-import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
-
-/** A view model for the wifi icon shown on keyguard (lockscreen). */
-class KeyguardWifiViewModel(
- statusBarPipelineFlags: StatusBarPipelineFlags,
- wifiIcon: StateFlow<WifiIcon>,
- isActivityInViewVisible: Flow<Boolean>,
- isActivityOutViewVisible: Flow<Boolean>,
- isActivityContainerVisible: Flow<Boolean>,
- isAirplaneSpacerVisible: Flow<Boolean>,
-) :
- LocationBasedWifiViewModel(
- statusBarPipelineFlags,
- debugTint = Color.MAGENTA,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
index 02c3a65..b731a41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt
@@ -17,10 +17,8 @@
package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
import android.graphics.Color
+import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
-import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
/**
* A view model for a wifi icon in a specific location. This allows us to control parameters that
@@ -29,24 +27,10 @@
* Must be subclassed for each distinct location.
*/
abstract class LocationBasedWifiViewModel(
+ val commonImpl: WifiViewModelCommon,
statusBarPipelineFlags: StatusBarPipelineFlags,
debugTint: Int,
-
- /** The wifi icon that should be displayed. */
- val wifiIcon: StateFlow<WifiIcon>,
-
- /** True if the activity in view should be visible. */
- val isActivityInViewVisible: Flow<Boolean>,
-
- /** True if the activity out view should be visible. */
- val isActivityOutViewVisible: Flow<Boolean>,
-
- /** True if the activity container view should be visible. */
- val isActivityContainerVisible: Flow<Boolean>,
-
- /** True if the airplane spacer view should be visible. */
- val isAirplaneSpacerVisible: Flow<Boolean>,
-) {
+) : WifiViewModelCommon by commonImpl {
val useDebugColoring: Boolean = statusBarPipelineFlags.useDebugColoring()
val defaultColor: Int =
@@ -55,4 +39,48 @@
} else {
Color.WHITE
}
+
+ companion object {
+ /**
+ * Returns a new instance of [LocationBasedWifiViewModel] that's specific to the given
+ * [location].
+ */
+ fun viewModelForLocation(
+ commonImpl: WifiViewModelCommon,
+ flags: StatusBarPipelineFlags,
+ location: StatusBarLocation,
+ ): LocationBasedWifiViewModel =
+ when (location) {
+ StatusBarLocation.HOME -> HomeWifiViewModel(commonImpl, flags)
+ StatusBarLocation.KEYGUARD -> KeyguardWifiViewModel(commonImpl, flags)
+ StatusBarLocation.QS -> QsWifiViewModel(commonImpl, flags)
+ }
+ }
}
+
+/**
+ * A view model for the wifi icon shown on the "home" page (aka, when the device is unlocked and not
+ * showing the shade, so the user is on the home-screen, or in an app).
+ */
+class HomeWifiViewModel(
+ commonImpl: WifiViewModelCommon,
+ statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+ WifiViewModelCommon,
+ LocationBasedWifiViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.CYAN)
+
+/** A view model for the wifi icon shown on keyguard (lockscreen). */
+class KeyguardWifiViewModel(
+ commonImpl: WifiViewModelCommon,
+ statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+ WifiViewModelCommon,
+ LocationBasedWifiViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.MAGENTA)
+
+/** A view model for the wifi icon shown in quick settings (when the shade is pulled down). */
+class QsWifiViewModel(
+ commonImpl: WifiViewModelCommon,
+ statusBarPipelineFlags: StatusBarPipelineFlags,
+) :
+ WifiViewModelCommon,
+ LocationBasedWifiViewModel(commonImpl, statusBarPipelineFlags, debugTint = Color.GREEN)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt
deleted file mode 100644
index 18e62b2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
-
-import android.graphics.Color
-import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
-import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
-
-/** A view model for the wifi icon shown in quick settings (when the shade is pulled down). */
-class QsWifiViewModel(
- statusBarPipelineFlags: StatusBarPipelineFlags,
- wifiIcon: StateFlow<WifiIcon>,
- isActivityInViewVisible: Flow<Boolean>,
- isActivityOutViewVisible: Flow<Boolean>,
- isActivityContainerVisible: Flow<Boolean>,
- isAirplaneSpacerVisible: Flow<Boolean>,
-) :
- LocationBasedWifiViewModel(
- statusBarPipelineFlags,
- debugTint = Color.GREEN,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
index 4b24e7a..c9a0786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
@@ -72,7 +72,7 @@
@Application private val scope: CoroutineScope,
statusBarPipelineFlags: StatusBarPipelineFlags,
wifiConstants: WifiConstants,
-) {
+) : WifiViewModelCommon {
/** Returns the icon to use based on the given network. */
private fun WifiNetworkModel.icon(): WifiIcon {
return when (this) {
@@ -106,8 +106,7 @@
}
}
- /** The wifi icon that should be displayed. */
- private val wifiIcon: StateFlow<WifiIcon> =
+ override val wifiIcon: StateFlow<WifiIcon> =
combine(
interactor.isEnabled,
interactor.isDefault,
@@ -162,17 +161,17 @@
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = default)
}
- private val isActivityInViewVisible: Flow<Boolean> =
+ override val isActivityInViewVisible: Flow<Boolean> =
activity
.map { it.hasActivityIn }
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
- private val isActivityOutViewVisible: Flow<Boolean> =
+ override val isActivityOutViewVisible: Flow<Boolean> =
activity
.map { it.hasActivityOut }
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
- private val isActivityContainerVisible: Flow<Boolean> =
+ override val isActivityContainerVisible: Flow<Boolean> =
combine(isActivityInViewVisible, isActivityOutViewVisible) { activityIn, activityOut ->
activityIn || activityOut
}
@@ -181,42 +180,9 @@
// TODO(b/238425913): It isn't ideal for the wifi icon to need to know about whether the
// airplane icon is visible. Instead, we should have a parent StatusBarSystemIconsViewModel
// that appropriately knows about both icons and sets the padding appropriately.
- private val isAirplaneSpacerVisible: Flow<Boolean> =
+ override val isAirplaneSpacerVisible: Flow<Boolean> =
airplaneModeViewModel.isAirplaneModeIconVisible
- /** A view model for the status bar on the home screen. */
- val home: HomeWifiViewModel =
- HomeWifiViewModel(
- statusBarPipelineFlags,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
-
- /** A view model for the status bar on keyguard. */
- val keyguard: KeyguardWifiViewModel =
- KeyguardWifiViewModel(
- statusBarPipelineFlags,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
-
- /** A view model for the status bar in quick settings. */
- val qs: QsWifiViewModel =
- QsWifiViewModel(
- statusBarPipelineFlags,
- wifiIcon,
- isActivityInViewVisible,
- isActivityOutViewVisible,
- isActivityContainerVisible,
- isAirplaneSpacerVisible,
- )
-
companion object {
@StringRes
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelCommon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelCommon.kt
new file mode 100644
index 0000000..eccf023
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelCommon.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.pipeline.wifi.ui.viewmodel
+
+import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * A common view model interface that can be used for delegation between [WifiViewModel] and
+ * [LocationBasedWifiViewModel].
+ */
+interface WifiViewModelCommon {
+ /** The wifi icon that should be displayed. */
+ val wifiIcon: StateFlow<WifiIcon>
+
+ /** True if the activity in view should be visible. */
+ val isActivityInViewVisible: Flow<Boolean>
+
+ /** True if the activity out view should be visible. */
+ val isActivityOutViewVisible: Flow<Boolean>
+
+ /** True if the activity container view should be visible. */
+ val isActivityContainerVisible: Flow<Boolean>
+
+ /** True if the airplane spacer view should be visible. */
+ val isAirplaneSpacerVisible: Flow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 2ee5232..654ba04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -57,6 +57,8 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.concurrent.GuardedBy;
+
/**
* Default implementation of a {@link BatteryController}. This controller monitors for battery
* level change events that are broadcasted by the system.
@@ -94,7 +96,10 @@
private boolean mTestMode = false;
@VisibleForTesting
boolean mHasReceivedBattery = false;
+ @GuardedBy("mEstimateLock")
private Estimate mEstimate;
+ private final Object mEstimateLock = new Object();
+
private boolean mFetchingEstimate = false;
// Use AtomicReference because we may request it from a different thread
@@ -321,7 +326,7 @@
@Nullable
private String generateTimeRemainingString() {
- synchronized (mFetchCallbacks) {
+ synchronized (mEstimateLock) {
if (mEstimate == null) {
return null;
}
@@ -340,7 +345,7 @@
mFetchingEstimate = true;
mBgHandler.post(() -> {
// Only fetch the estimate if they are enabled
- synchronized (mFetchCallbacks) {
+ synchronized (mEstimateLock) {
mEstimate = null;
if (mEstimates.isHybridNotificationEnabled()) {
updateEstimate();
@@ -363,6 +368,7 @@
}
@WorkerThread
+ @GuardedBy("mEstimateLock")
private void updateEstimate() {
Assert.isNotMainThread();
// if the estimate has been cached we can just use that, otherwise get a new one and
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
index 0c5b851..3429e25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
@@ -16,12 +16,15 @@
package com.android.systemui.statusbar.policy;
+import android.bluetooth.BluetoothAdapter;
+
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.policy.BluetoothController.Callback;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.Executor;
public interface BluetoothController extends CallbackController<Callback>, Dumpable {
boolean isBluetoothSupported();
@@ -44,6 +47,11 @@
int getBondState(CachedBluetoothDevice device);
List<CachedBluetoothDevice> getConnectedDevices();
+ void addOnMetadataChangedListener(CachedBluetoothDevice device, Executor executor,
+ BluetoothAdapter.OnMetadataChangedListener listener);
+ void removeOnMetadataChangedListener(CachedBluetoothDevice device,
+ BluetoothAdapter.OnMetadataChangedListener listener);
+
public interface Callback {
void onBluetoothStateChange(boolean enabled);
void onBluetoothDevicesChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index acdf0d2..c804fe7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -48,6 +48,7 @@
import java.util.Collection;
import java.util.List;
import java.util.WeakHashMap;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -78,6 +79,7 @@
private final H mHandler;
private int mState;
+ private final BluetoothAdapter mAdapter;
/**
*/
@Inject
@@ -88,7 +90,8 @@
BluetoothLogger logger,
@Background Looper bgLooper,
@Main Looper mainLooper,
- @Nullable LocalBluetoothManager localBluetoothManager) {
+ @Nullable LocalBluetoothManager localBluetoothManager,
+ @Nullable BluetoothAdapter bluetoothAdapter) {
mDumpManager = dumpManager;
mLogger = logger;
mLocalBluetoothManager = localBluetoothManager;
@@ -103,6 +106,7 @@
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mCurrentUser = userTracker.getUserId();
mDumpManager.registerDumpable(TAG, this);
+ mAdapter = bluetoothAdapter;
}
@Override
@@ -412,6 +416,30 @@
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
+ public void addOnMetadataChangedListener(
+ @NonNull CachedBluetoothDevice cachedDevice,
+ Executor executor,
+ BluetoothAdapter.OnMetadataChangedListener listener
+ ) {
+ if (mAdapter == null) return;
+ mAdapter.addOnMetadataChangedListener(
+ cachedDevice.getDevice(),
+ executor,
+ listener
+ );
+ }
+
+ public void removeOnMetadataChangedListener(
+ @NonNull CachedBluetoothDevice cachedDevice,
+ BluetoothAdapter.OnMetadataChangedListener listener
+ ) {
+ if (mAdapter == null) return;
+ mAdapter.removeOnMetadataChangedListener(
+ cachedDevice.getDevice(),
+ listener
+ );
+ }
+
private ActuallyCachedState getCachedState(CachedBluetoothDevice device) {
ActuallyCachedState state = mCachedState.get(device);
if (state == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
index 166ac9e..f09b2f7 100644
--- a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
@@ -21,6 +21,7 @@
import android.util.Log;
import android.view.AttachedSurfaceControl;
import android.view.View;
+import android.view.ViewGroup;
import androidx.concurrent.futures.CallbackToFutureAdapter;
@@ -118,7 +119,9 @@
affectedSurfaces.put(surface, Region.obtain());
}
final Rect boundaries = new Rect();
- view.getBoundsOnScreen(boundaries);
+ view.getDrawingRect(boundaries);
+ ((ViewGroup) view.getRootView())
+ .offsetDescendantRectToMyCoords(view, boundaries);
affectedSurfaces.get(surface).op(boundaries, Region.Op.UNION);
});
mManager.setTouchRegions(this, affectedSurfaces);
diff --git a/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java b/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java
new file mode 100644
index 0000000..8acd653
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/display/DisplayHelper.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 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.util.display;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.view.Display;
+import android.view.WindowManager;
+
+import javax.inject.Inject;
+
+/**
+ * Utility class for working with displays.
+ */
+public class DisplayHelper {
+ private final Context mContext;
+ private final DisplayManager mDisplayManager;
+
+ /**
+ * Default constructor.
+ */
+ @Inject
+ public DisplayHelper(Context context, DisplayManager displayManager) {
+ mContext = context;
+ mDisplayManager = displayManager;
+ }
+
+
+ /**
+ * Returns the maximum display bounds for the given window context type.
+ */
+ public Rect getMaxBounds(int displayId, int windowContextType) {
+ final Display display = mDisplayManager.getDisplay(displayId);
+ WindowManager windowManager = mContext.createDisplayContext(display)
+ .createWindowContext(windowContextType, null)
+ .getSystemService(WindowManager.class);
+ return windowManager.getMaximumWindowMetrics().getBounds();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletCardsUpdatedListener.aidl b/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletCardsUpdatedListener.aidl
new file mode 100644
index 0000000..aa7ef57
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletCardsUpdatedListener.aidl
@@ -0,0 +1,7 @@
+package com.android.systemui.wallet.controller;
+
+import android.service.quickaccesswallet.WalletCard;
+
+interface IWalletCardsUpdatedListener {
+ void registerNewWalletCards(in List<WalletCard> cards);
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletContextualLocationsService.aidl b/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletContextualLocationsService.aidl
new file mode 100644
index 0000000..eebbdfd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/IWalletContextualLocationsService.aidl
@@ -0,0 +1,9 @@
+package com.android.systemui.wallet.controller;
+
+import com.android.systemui.wallet.controller.IWalletCardsUpdatedListener;
+
+interface IWalletContextualLocationsService {
+ void addWalletCardsUpdatedListener(in IWalletCardsUpdatedListener listener);
+
+ void onWalletContextualLocationsStateUpdated(in List<String> storeLocations);
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 2ef3511..29680d8 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system"
- package="com.android.systemui" >
+ package="com.android.systemui.tests" >
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
@@ -64,7 +64,7 @@
</intent-filter>
</receiver>
- <activity android:name=".wmshell.BubblesTestActivity"
+ <activity android:name="com.android.systemui.wmshell.BubblesTestActivity"
android:allowEmbedded="true"
android:documentLaunchMode="always"
android:excludeFromRecents="true"
@@ -88,7 +88,7 @@
android:excludeFromRecents="true"
/>
- <activity android:name=".settings.brightness.BrightnessDialogTest$TestDialog"
+ <activity android:name="com.android.systemui.settings.brightness.BrightnessDialogTest$TestDialog"
android:exported="false"
android:excludeFromRecents="true"
/>
@@ -108,6 +108,11 @@
android:excludeFromRecents="true"
/>
+ <activity android:name="com.android.systemui.controls.ui.TestableControlsActivity"
+ android:exported="false"
+ android:excludeFromRecents="true"
+ />
+
<activity android:name="com.android.systemui.screenshot.ScrollViewActivity"
android:exported="false" />
@@ -115,19 +120,19 @@
android:exported="false" />
<!-- started from UsbDeviceSettingsManager -->
- <activity android:name=".usb.UsbPermissionActivityTest$UsbPermissionActivityTestable"
+ <activity android:name="com.android.systemui.usb.UsbPermissionActivityTest$UsbPermissionActivityTestable"
android:exported="false"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true" />
- <activity android:name=".user.CreateUserActivityTest$CreateUserActivityTestable"
+ <activity android:name="com.android.systemui.user.CreateUserActivityTest$CreateUserActivityTestable"
android:exported="false"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true" />
- <activity android:name=".sensorprivacy.SensorUseStartedActivityTest$SensorUseStartedActivityTestable"
+ <activity android:name="com.android.systemui.sensorprivacy.SensorUseStartedActivityTest$SensorUseStartedActivityTestable"
android:exported="false"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
diff --git a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
index 0369d5b..ec6c421 100644
--- a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
+++ b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
@@ -59,7 +59,7 @@
private static final String TAG = "AAA++VerifyTest";
- private static final Class[] BASE_CLS_WHITELIST = {
+ private static final Class[] BASE_CLS_TO_INCLUDE = {
SysuiTestCase.class,
SysuiBaseFragmentTest.class,
};
@@ -81,7 +81,7 @@
if (!isTestClass(cls)) continue;
boolean hasParent = false;
- for (Class<?> parent : BASE_CLS_WHITELIST) {
+ for (Class<?> parent : BASE_CLS_TO_INCLUDE) {
if (parent.isAssignableFrom(cls)) {
hasParent = true;
break;
@@ -131,13 +131,13 @@
// with the main process dependency graph because it will not exist
// at runtime and could lead to incorrect tests which assume
// the main SystemUI process. Therefore, exclude this package
- // from the base class whitelist.
+ // from the base class allowlist.
filter.add(s -> !s.startsWith("com.android.systemui.screenshot"));
return filter;
}
private String getClsStr() {
- return TextUtils.join(",", Arrays.asList(BASE_CLS_WHITELIST)
+ return TextUtils.join(",", Arrays.asList(BASE_CLS_TO_INCLUDE)
.stream().map(cls -> cls.getSimpleName()).toArray());
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index fb21db7..a8b4254 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -2159,8 +2159,7 @@
keyguardIsVisible();
verifyFaceAuthenticateCall();
- verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
- anyInt());
+ verifyFingerprintAuthenticateCall();
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal);
@@ -2627,8 +2626,7 @@
}
private void verifyFingerprintAuthenticateCall() {
- verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
- anyInt());
+ verify(mFingerprintManager).authenticate(any(), any(), any(), any(), any());
}
private void verifyFingerprintDetectNeverCalled() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt
new file mode 100644
index 0000000..44da5f4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserPinMigrationTest.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2023 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
+
+import android.content.Context
+import android.content.Intent
+import android.content.SharedPreferences
+import android.content.res.Resources
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.kotlinArgumentCaptor
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import java.io.File
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ChooserPinMigrationTest : SysuiTestCase() {
+
+ private val fakeFeatureFlags = FakeFeatureFlags()
+ private val fakePreferences =
+ mutableMapOf(
+ "TestPinnedPackage/TestPinnedClass" to true,
+ "TestUnpinnedPackage/TestUnpinnedClass" to false,
+ )
+ private val intent = kotlinArgumentCaptor<Intent>()
+ private val permission = kotlinArgumentCaptor<String>()
+
+ private lateinit var chooserPinMigration: ChooserPinMigration
+
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var mockResources: Resources
+ @Mock
+ private lateinit var mockLegacyPinPrefsFileSupplier:
+ ChooserPinMigration.Companion.LegacyPinPrefsFileSupplier
+ @Mock private lateinit var mockFile: File
+ @Mock private lateinit var mockSharedPreferences: SharedPreferences
+ @Mock private lateinit var mockSharedPreferencesEditor: SharedPreferences.Editor
+ @Mock private lateinit var mockBroadcastSender: BroadcastSender
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+
+ whenever(mockContext.resources).thenReturn(mockResources)
+ whenever(mockContext.getSharedPreferences(any<File>(), anyInt()))
+ .thenReturn(mockSharedPreferences)
+ whenever(mockResources.getString(anyInt())).thenReturn("TestPackage/TestClass")
+ whenever(mockSharedPreferences.all).thenReturn(fakePreferences)
+ whenever(mockSharedPreferences.edit()).thenReturn(mockSharedPreferencesEditor)
+ whenever(mockSharedPreferencesEditor.commit()).thenReturn(true)
+ whenever(mockLegacyPinPrefsFileSupplier.get()).thenReturn(mockFile)
+ whenever(mockFile.exists()).thenReturn(true)
+ whenever(mockFile.delete()).thenReturn(true)
+ fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, true)
+ }
+
+ @Test
+ fun start_performsMigration() {
+ // Arrange
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
+ assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
+ assertThat(intent.value.`package`).isEqualTo("TestPackage")
+ assertThat(intent.value.extras?.keySet()).hasSize(2)
+ assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
+ assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
+ .isTrue()
+ assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
+ assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
+ .isFalse()
+ assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
+
+ // Assert
+ verify(mockSharedPreferencesEditor).clear()
+ verify(mockSharedPreferencesEditor).commit()
+
+ // Assert
+ verify(mockFile).delete()
+ }
+
+ @Test
+ fun start_doesNotDeleteLegacyPreferencesFile_whenClearingItFails() {
+ // Arrange
+ whenever(mockSharedPreferencesEditor.commit()).thenReturn(false)
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
+ assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
+ assertThat(intent.value.`package`).isEqualTo("TestPackage")
+ assertThat(intent.value.extras?.keySet()).hasSize(2)
+ assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
+ assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
+ .isTrue()
+ assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
+ assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
+ .isFalse()
+ assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
+
+ // Assert
+ verify(mockSharedPreferencesEditor).clear()
+ verify(mockSharedPreferencesEditor).commit()
+
+ // Assert
+ verify(mockFile, never()).delete()
+ }
+
+ @Test
+ fun start_OnlyDeletesLegacyPreferencesFile_whenEmpty() {
+ // Arrange
+ whenever(mockSharedPreferences.all).thenReturn(emptyMap())
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verifyZeroInteractions(mockBroadcastSender)
+
+ // Assert
+ verifyZeroInteractions(mockSharedPreferencesEditor)
+
+ // Assert
+ verify(mockFile).delete()
+ }
+
+ @Test
+ fun start_DoesNotDoMigration_whenFlagIsDisabled() {
+ // Arrange
+ fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, false)
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verifyZeroInteractions(mockBroadcastSender)
+
+ // Assert
+ verifyZeroInteractions(mockSharedPreferencesEditor)
+
+ // Assert
+ verify(mockFile, never()).delete()
+ }
+
+ @Test
+ fun start_DoesNotDoMigration_whenLegacyPreferenceFileNotPresent() {
+ // Arrange
+ whenever(mockFile.exists()).thenReturn(false)
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verifyZeroInteractions(mockBroadcastSender)
+
+ // Assert
+ verifyZeroInteractions(mockSharedPreferencesEditor)
+
+ // Assert
+ verify(mockFile, never()).delete()
+ }
+
+ @Test
+ fun start_DoesNotDoMigration_whenConfiguredChooserComponentIsInvalid() {
+ // Arrange
+ whenever(mockResources.getString(anyInt())).thenReturn("InvalidComponent")
+ chooserPinMigration =
+ ChooserPinMigration(
+ mockContext,
+ fakeFeatureFlags,
+ mockBroadcastSender,
+ mockLegacyPinPrefsFileSupplier,
+ )
+
+ // Act
+ chooserPinMigration.start()
+
+ // Assert
+ verifyZeroInteractions(mockBroadcastSender)
+
+ // Assert
+ verifyZeroInteractions(mockSharedPreferencesEditor)
+
+ // Assert
+ verify(mockFile, never()).delete()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
new file mode 100644
index 0000000..6ddba0b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 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.biometrics
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.ShadeExpansionStateManager
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.timeout
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() {
+
+ private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
+ private lateinit var detector: AuthDialogPanelInteractionDetector
+
+ @Mock private lateinit var action: Runnable
+
+ @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+ @Before
+ fun setUp() {
+ shadeExpansionStateManager = ShadeExpansionStateManager()
+ detector =
+ AuthDialogPanelInteractionDetector(shadeExpansionStateManager, mContext.mainExecutor)
+ }
+
+ @Test
+ fun testEnableDetector_shouldPostRunnable() {
+ detector.enable(action)
+ // simulate notification expand
+ shadeExpansionStateManager.onPanelExpansionChanged(5566f, true, true, 5566f)
+ verify(action, timeout(5000).times(1)).run()
+ }
+
+ @Test
+ fun testEnableDetector_shouldNotPostRunnable() {
+ var detector =
+ AuthDialogPanelInteractionDetector(shadeExpansionStateManager, mContext.mainExecutor)
+ detector.enable(action)
+ detector.disable()
+ shadeExpansionStateManager.onPanelExpansionChanged(5566f, true, true, 5566f)
+ verifyZeroInteractions(action)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 6e423593..a245c01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -17,14 +17,14 @@
package com.android.systemui.biometrics
import android.graphics.Point
-import android.hardware.biometrics.BiometricSourceType.FACE
-import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
+import android.hardware.biometrics.BiometricSourceType
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.keyguard.logging.KeyguardLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.logcatLogBuffer
@@ -36,11 +36,11 @@
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.leak.RotationUtils
import com.android.systemui.util.mockito.any
-import javax.inject.Provider
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -50,15 +50,15 @@
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
import org.mockito.Mock
+import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.MockitoSession
import org.mockito.quality.Strictness
+import javax.inject.Provider
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -75,6 +75,7 @@
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
+ @Mock private lateinit var bypassController: KeyguardBypassController
@Mock private lateinit var biometricUnlockController: BiometricUnlockController
@Mock private lateinit var udfpsControllerProvider: Provider<UdfpsController>
@Mock private lateinit var udfpsController: UdfpsController
@@ -83,15 +84,10 @@
@Mock private lateinit var lightRevealScrim: LightRevealScrim
@Mock private lateinit var fpSensorProp: FingerprintSensorPropertiesInternal
- @Captor
- private lateinit var biometricModeListener:
- ArgumentCaptor<BiometricUnlockController.BiometricModeListener>
-
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- staticMockSession =
- mockitoSession()
+ staticMockSession = mockitoSession()
.mockStatic(RotationUtils::class.java)
.strictness(Strictness.LENIENT)
.startMocking()
@@ -100,24 +96,24 @@
`when`(authController.udfpsProps).thenReturn(listOf(fpSensorProp))
`when`(udfpsControllerProvider.get()).thenReturn(udfpsController)
- controller =
- AuthRippleController(
- mCentralSurfaces,
- context,
- authController,
- configurationController,
- keyguardUpdateMonitor,
- keyguardStateController,
- wakefulnessLifecycle,
- commandRegistry,
- notificationShadeWindowController,
- biometricUnlockController,
- udfpsControllerProvider,
- statusBarStateController,
- featureFlags,
- KeyguardLogger(logcatLogBuffer(AuthRippleController.TAG)),
- rippleView
- )
+ controller = AuthRippleController(
+ mCentralSurfaces,
+ context,
+ authController,
+ configurationController,
+ keyguardUpdateMonitor,
+ keyguardStateController,
+ wakefulnessLifecycle,
+ commandRegistry,
+ notificationShadeWindowController,
+ bypassController,
+ biometricUnlockController,
+ udfpsControllerProvider,
+ statusBarStateController,
+ featureFlags,
+ KeyguardLogger(logcatLogBuffer(AuthRippleController.TAG)),
+ rippleView
+ )
controller.init()
`when`(mCentralSurfaces.lightRevealScrim).thenReturn(lightRevealScrim)
}
@@ -134,14 +130,16 @@
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardStateController.isShowing).thenReturn(true)
- `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(eq(FINGERPRINT)))
- .thenReturn(true)
- `when`(biometricUnlockController.isBiometricUnlock).thenReturn(true)
- `when`(biometricUnlockController.biometricType).thenReturn(FINGERPRINT)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
- // WHEN unlocked with fingerprint
- verify(biometricUnlockController).addBiometricModeListener(biometricModeListener.capture())
- biometricModeListener.value.onModeChanged(/* mode= */ 0)
+ // WHEN fingerprint authenticated
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FINGERPRINT /* type */,
+ false /* isStrongBiometric */)
// THEN update sensor location and show ripple
verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f)
@@ -154,15 +152,17 @@
val fpsLocation = Point(5, 5)
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
controller.onViewAttached()
- `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(eq(FINGERPRINT)))
- .thenReturn(true)
- `when`(biometricUnlockController.isBiometricUnlock).thenReturn(true)
- `when`(biometricUnlockController.biometricType).thenReturn(FINGERPRINT)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
// WHEN keyguard is NOT showing & fingerprint authenticated
`when`(keyguardStateController.isShowing).thenReturn(false)
- verify(biometricUnlockController).addBiometricModeListener(biometricModeListener.capture())
- biometricModeListener.value.onModeChanged(/* mode= */ 0)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FINGERPRINT /* type */,
+ false /* isStrongBiometric */)
// THEN no ripple
verify(rippleView, never()).startUnlockedRipple(any())
@@ -175,14 +175,61 @@
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardStateController.isShowing).thenReturn(true)
- `when`(biometricUnlockController.isBiometricUnlock).thenReturn(true)
- `when`(biometricUnlockController.biometricType).thenReturn(FINGERPRINT)
// WHEN unlocking with fingerprint is NOT allowed & fingerprint authenticated
- `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(eq(FINGERPRINT)))
- .thenReturn(false)
- verify(biometricUnlockController).addBiometricModeListener(biometricModeListener.capture())
- biometricModeListener.value.onModeChanged(/* mode= */ 0)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ eq(BiometricSourceType.FINGERPRINT))).thenReturn(false)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FINGERPRINT /* type */,
+ false /* isStrongBiometric */)
+
+ // THEN no ripple
+ verify(rippleView, never()).startUnlockedRipple(any())
+ }
+
+ @Test
+ fun testFaceTriggerBypassEnabled_Ripple() {
+ // GIVEN face auth sensor exists, keyguard is showing & unlocking with face is allowed
+ val faceLocation = Point(5, 5)
+ `when`(authController.faceSensorLocation).thenReturn(faceLocation)
+ controller.onViewAttached()
+
+ `when`(keyguardStateController.isShowing).thenReturn(true)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ BiometricSourceType.FACE)).thenReturn(true)
+
+ // WHEN bypass is enabled & face authenticated
+ `when`(bypassController.canBypass()).thenReturn(true)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FACE /* type */,
+ false /* isStrongBiometric */)
+
+ // THEN show ripple
+ verify(rippleView).setSensorLocation(faceLocation)
+ verify(rippleView).startUnlockedRipple(any())
+ }
+
+ @Test
+ fun testFaceTriggerNonBypass_NoRipple() {
+ // GIVEN face auth sensor exists
+ val faceLocation = Point(5, 5)
+ `when`(authController.faceSensorLocation).thenReturn(faceLocation)
+ controller.onViewAttached()
+
+ // WHEN bypass isn't enabled & face authenticated
+ `when`(bypassController.canBypass()).thenReturn(false)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FACE /* type */,
+ false /* isStrongBiometric */)
// THEN no ripple
verify(rippleView, never()).startUnlockedRipple(any())
@@ -192,12 +239,14 @@
fun testNullFaceSensorLocationDoesNothing() {
`when`(authController.faceSensorLocation).thenReturn(null)
controller.onViewAttached()
- `when`(biometricUnlockController.biometricType).thenReturn(FACE)
- `when`(biometricUnlockController.isBiometricUnlock).thenReturn(true)
- verify(biometricUnlockController).addBiometricModeListener(biometricModeListener.capture())
- biometricModeListener.value.onModeChanged(/* mode= */ 0)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FACE /* type */,
+ false /* isStrongBiometric */)
verify(rippleView, never()).startUnlockedRipple(any())
}
@@ -205,21 +254,25 @@
fun testNullFingerprintSensorLocationDoesNothing() {
`when`(authController.fingerprintSensorLocation).thenReturn(null)
controller.onViewAttached()
- `when`(biometricUnlockController.biometricType).thenReturn(FINGERPRINT)
- `when`(biometricUnlockController.isBiometricUnlock).thenReturn(true)
- verify(biometricUnlockController).addBiometricModeListener(biometricModeListener.capture())
- biometricModeListener.value.onModeChanged(/* mode= */ 0)
+ val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
+ verify(keyguardUpdateMonitor).registerCallback(captor.capture())
+ captor.value.onBiometricAuthenticated(
+ 0 /* userId */,
+ BiometricSourceType.FINGERPRINT /* type */,
+ false /* isStrongBiometric */)
verify(rippleView, never()).startUnlockedRipple(any())
}
@Test
fun registersAndDeregisters() {
controller.onViewAttached()
- val captor = ArgumentCaptor.forClass(KeyguardStateController.Callback::class.java)
+ val captor = ArgumentCaptor
+ .forClass(KeyguardStateController.Callback::class.java)
verify(keyguardStateController).addCallback(captor.capture())
- val captor2 = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
+ val captor2 = ArgumentCaptor
+ .forClass(WakefulnessLifecycle.Observer::class.java)
verify(wakefulnessLifecycle).addObserver(captor2.capture())
controller.onViewDetached()
verify(keyguardStateController).removeCallback(any())
@@ -233,20 +286,17 @@
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
controller.onViewAttached()
`when`(keyguardStateController.isShowing).thenReturn(true)
- `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(FINGERPRINT)).thenReturn(true)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ BiometricSourceType.FINGERPRINT)).thenReturn(true)
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
- controller.showUnlockRipple(FINGERPRINT)
- assertTrue(
- "reveal didn't start on keyguardFadingAway",
- controller.startLightRevealScrimOnKeyguardFadingAway
- )
+ controller.showUnlockRipple(BiometricSourceType.FINGERPRINT)
+ assertTrue("reveal didn't start on keyguardFadingAway",
+ controller.startLightRevealScrimOnKeyguardFadingAway)
`when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
controller.onKeyguardFadingAwayChanged()
- assertFalse(
- "reveal triggers multiple times",
- controller.startLightRevealScrimOnKeyguardFadingAway
- )
+ assertFalse("reveal triggers multiple times",
+ controller.startLightRevealScrimOnKeyguardFadingAway)
}
@Test
@@ -258,26 +308,23 @@
`when`(keyguardStateController.isShowing).thenReturn(true)
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
`when`(authController.isUdfpsFingerDown).thenReturn(true)
- `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(eq(FACE))).thenReturn(true)
+ `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
+ eq(BiometricSourceType.FACE))).thenReturn(true)
- controller.showUnlockRipple(FACE)
- assertTrue(
- "reveal didn't start on keyguardFadingAway",
- controller.startLightRevealScrimOnKeyguardFadingAway
- )
+ controller.showUnlockRipple(BiometricSourceType.FACE)
+ assertTrue("reveal didn't start on keyguardFadingAway",
+ controller.startLightRevealScrimOnKeyguardFadingAway)
`when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
controller.onKeyguardFadingAwayChanged()
- assertFalse(
- "reveal triggers multiple times",
- controller.startLightRevealScrimOnKeyguardFadingAway
- )
+ assertFalse("reveal triggers multiple times",
+ controller.startLightRevealScrimOnKeyguardFadingAway)
}
@Test
fun testUpdateRippleColor() {
controller.onViewAttached()
- val captor =
- ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
+ val captor = ArgumentCaptor
+ .forClass(ConfigurationController.ConfigurationListener::class.java)
verify(configurationController).addCallback(captor.capture())
reset(rippleView)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
index 5c09240..c2a129b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
@@ -49,7 +49,6 @@
private lateinit var udfpsShell: UdfpsShell
@Mock lateinit var commandRegistry: CommandRegistry
- @Mock lateinit var udfpsOverlay: UdfpsOverlay
@Mock lateinit var udfpsOverlayController: UdfpsOverlayController
@Captor private lateinit var motionEvent: ArgumentCaptor<MotionEvent>
@@ -60,7 +59,7 @@
fun setup() {
whenEver(udfpsOverlayController.sensorBounds).thenReturn(sensorBounds)
- udfpsShell = UdfpsShell(commandRegistry, udfpsOverlay)
+ udfpsShell = UdfpsShell(commandRegistry)
udfpsShell.udfpsOverlayController = udfpsOverlayController
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index 3eb82a7..94489ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -1,19 +1,22 @@
package com.android.systemui.biometrics.domain.interactor
+import android.hardware.biometrics.AuthenticateOptions
import android.hardware.biometrics.IBiometricContextListener
import android.hardware.biometrics.IBiometricContextListener.FoldState
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.WakefulnessLifecycle
-import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
import com.android.systemui.unfold.updates.FoldStateProvider
-import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -38,63 +41,122 @@
private val testScope = TestScope()
- @Mock private lateinit var statusBarStateController: StatusBarStateController
- @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock private lateinit var foldProvider: FoldStateProvider
+ private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
+
private lateinit var interactor: LogContextInteractorImpl
@Before
fun setup() {
+ keyguardTransitionRepository = FakeKeyguardTransitionRepository()
interactor =
LogContextInteractorImpl(
testScope.backgroundScope,
- statusBarStateController,
- wakefulnessLifecycle,
- foldProvider
+ foldProvider,
+ KeyguardTransitionInteractor(
+ keyguardTransitionRepository,
+ ),
)
}
@Test
- fun isDozingChanges() =
+ fun isAodChanges() =
testScope.runTest {
- whenever(statusBarStateController.isDozing).thenReturn(true)
+ val isAod = collectLastValue(interactor.isAod)
- val isDozing = collectLastValue(interactor.isDozing)
- runCurrent()
- val listener = statusBarStateController.captureListener()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
+ assertThat(isAod()).isFalse()
- assertThat(isDozing()).isTrue()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+ assertThat(isAod()).isFalse()
- listener.onDozingChanged(true)
- listener.onDozingChanged(true)
- listener.onDozingChanged(false)
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
+ assertThat(isAod()).isFalse()
- assertThat(isDozing()).isFalse()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(isAod()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(isAod()).isFalse()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(isAod()).isFalse()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+ assertThat(isAod()).isFalse()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+ assertThat(isAod()).isFalse()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+ assertThat(isAod()).isFalse()
}
@Test
fun isAwakeChanges() =
testScope.runTest {
- whenever(wakefulnessLifecycle.wakefulness)
- .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE)
-
val isAwake = collectLastValue(interactor.isAwake)
- runCurrent()
- val listener = wakefulnessLifecycle.captureObserver()
- assertThat(isAwake()).isTrue()
-
- listener.onStartedGoingToSleep()
- listener.onFinishedGoingToSleep()
- listener.onStartedWakingUp()
-
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
assertThat(isAwake()).isFalse()
- listener.onFinishedWakingUp()
- listener.onPostFinishedWakingUp()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+ assertThat(isAwake()).isFalse()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
assertThat(isAwake()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(isAwake()).isFalse()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(isAwake()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(isAwake()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+ assertThat(isAwake()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+ assertThat(isAwake()).isTrue()
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+ assertThat(isAwake()).isTrue()
+ }
+
+ @Test
+ fun displayStateChanges() =
+ testScope.runTest {
+ val displayState = collectLastValue(interactor.displayState)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_SCREENSAVER)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+ assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
}
@Test
@@ -123,74 +185,66 @@
@Test
fun contextSubscriberChanges() =
testScope.runTest {
- whenever(statusBarStateController.isDozing).thenReturn(false)
- whenever(wakefulnessLifecycle.wakefulness)
- .thenReturn(WakefulnessLifecycle.WAKEFULNESS_AWAKE)
runCurrent()
-
val foldListener = foldProvider.captureListener()
foldListener.onFoldUpdate(FOLD_UPDATE_START_CLOSING)
foldListener.onFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
- var dozing: Boolean? = null
+ var aod: Boolean? = null
var awake: Boolean? = null
var folded: Int? = null
+ var displayState: Int? = null
val job =
interactor.addBiometricContextListener(
object : IBiometricContextListener.Stub() {
- override fun onDozeChanged(isDozing: Boolean, isAwake: Boolean) {
- dozing = isDozing
+ override fun onDozeChanged(isAod: Boolean, isAwake: Boolean) {
+ aod = isAod
awake = isAwake
}
override fun onFoldChanged(foldState: Int) {
folded = foldState
}
+
+ override fun onDisplayStateChanged(newDisplayState: Int) {
+ displayState = newDisplayState
+ }
}
)
runCurrent()
- val statusBarStateListener = statusBarStateController.captureListener()
- val wakefullnessObserver = wakefulnessLifecycle.captureObserver()
-
- assertThat(dozing).isFalse()
- assertThat(awake).isTrue()
+ assertThat(aod).isTrue()
+ assertThat(awake).isFalse()
assertThat(folded).isEqualTo(FoldState.FULLY_CLOSED)
+ assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
- statusBarStateListener.onDozingChanged(true)
- wakefullnessObserver.onStartedGoingToSleep()
foldListener.onFoldUpdate(FOLD_UPDATE_START_OPENING)
foldListener.onFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN)
- wakefullnessObserver.onFinishedGoingToSleep()
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
runCurrent()
- assertThat(dozing).isTrue()
- assertThat(awake).isFalse()
+ assertThat(aod).isFalse()
+ assertThat(awake).isTrue()
assertThat(folded).isEqualTo(FoldState.HALF_OPENED)
+ assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
job.cancel()
// stale updates should be ignored
- statusBarStateListener.onDozingChanged(false)
- wakefullnessObserver.onFinishedWakingUp()
foldListener.onFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN)
+ keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
runCurrent()
- assertThat(dozing).isTrue()
- assertThat(awake).isFalse()
+ assertThat(aod).isFalse()
+ assertThat(awake).isTrue()
assertThat(folded).isEqualTo(FoldState.HALF_OPENED)
+ assertThat(displayState).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
}
}
-private fun StatusBarStateController.captureListener() =
- withArgCaptor<StatusBarStateController.StateListener> {
- verify(this@captureListener).addCallback(capture())
- }
-
-private fun WakefulnessLifecycle.captureObserver() =
- withArgCaptor<WakefulnessLifecycle.Observer> {
- verify(this@captureObserver).addObserver(capture())
- }
+private suspend fun FakeKeyguardTransitionRepository.startTransitionTo(newState: KeyguardState) =
+ sendTransitionStep(TransitionStep(to = newState, transitionState = TransitionState.STARTED))
private fun FoldStateProvider.captureListener() =
withArgCaptor<FoldStateProvider.FoldUpdatesListener> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
index 9d16185..6fa1916 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
@@ -18,7 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -29,7 +33,11 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -47,6 +55,12 @@
private static final String CURRENT_BROADCAST_APP = "Music";
private static final String SWITCH_APP = "System UI";
private static final String TEST_PACKAGE = "com.android.systemui";
+ private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
+ private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
+ LocalBluetoothProfileManager.class);
+ private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
+ LocalBluetoothLeBroadcast.class);
+ private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
private BroadcastDialog mBroadcastDialog;
private View mDialogView;
private TextView mTitle;
@@ -57,9 +71,11 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
mBroadcastDialog = new BroadcastDialog(mContext, mock(MediaOutputDialogFactory.class),
- CURRENT_BROADCAST_APP, TEST_PACKAGE, mock(UiEventLogger.class));
-
+ mLocalBluetoothManager, CURRENT_BROADCAST_APP, TEST_PACKAGE,
+ mock(UiEventLogger.class), mBroadcastSender);
mBroadcastDialog.show();
mDialogView = mBroadcastDialog.mDialogView;
}
@@ -100,4 +116,61 @@
assertThat(mBroadcastDialog.isShowing()).isFalse();
}
+
+ @Test
+ public void onClick_withSwitchBroadcast_stopCurrentBroadcast() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ mSwitchBroadcastAppButton = mDialogView.requireViewById(R.id.switch_broadcast);
+ mSwitchBroadcastAppButton.performClick();
+
+ verify(mLocalBluetoothLeBroadcast).stopLatestBroadcast();
+ }
+
+ @Test
+ public void onClick_withSwitchBroadcast_stopCurrentBroadcastFailed() {
+ mSwitchBroadcastAppButton = mDialogView.requireViewById(R.id.switch_broadcast);
+ mSwitchBroadcastAppButton.performClick();
+
+ assertThat(mSwitchBroadcastAppButton.getText().toString()).isEqualTo(
+ mContext.getString(R.string.bt_le_audio_broadcast_dialog_switch_app, SWITCH_APP));
+ }
+
+ @Test
+ public void handleLeBroadcastStopped_withBroadcastProfileNull_doRefreshButton() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
+ mSwitchBroadcastAppButton = mDialogView.requireViewById(R.id.switch_broadcast);
+
+ mBroadcastDialog.handleLeBroadcastStopped();
+
+ assertThat(mSwitchBroadcastAppButton.getText().toString()).isEqualTo(
+ mContext.getString(R.string.bt_le_audio_broadcast_dialog_switch_app, SWITCH_APP));
+ }
+
+ @Test
+ public void handleLeBroadcastStopped_withBroadcastProfile_doStartBroadcast() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+
+ mBroadcastDialog.handleLeBroadcastStopped();
+
+ verify(mLocalBluetoothLeBroadcast).startBroadcast(eq(SWITCH_APP), any());
+ }
+
+ @Test
+ public void handleLeBroadcastMetadataChanged_withNotLaunchFlag_doNotDismissDialog() {
+
+ mBroadcastDialog.handleLeBroadcastMetadataChanged();
+
+ assertThat(mBroadcastDialog.isShowing()).isTrue();
+ }
+
+ @Test
+ public void handleLeBroadcastMetadataChanged_withLaunchFlag_dismissDialog() {
+
+ mBroadcastDialog.handleLeBroadcastStarted();
+ mBroadcastDialog.handleLeBroadcastMetadataChanged();
+
+ assertThat(mBroadcastDialog.isShowing()).isFalse();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
new file mode 100644
index 0000000..0f62b24
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 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.controls.ui
+
+import android.content.Intent
+import android.content.res.Configuration
+import android.service.dreams.IDreamManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import androidx.test.runner.intercepting.SingleActivityFactory
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.controls.settings.ControlsSettingsDialogManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class ControlsActivityTest : SysuiTestCase() {
+ @Mock private lateinit var uiController: ControlsUiController
+ @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock private lateinit var dreamManager: IDreamManager
+ @Mock private lateinit var featureFlags: FeatureFlags
+ @Mock private lateinit var controlsSettingsDialogManager: ControlsSettingsDialogManager
+ @Mock private lateinit var keyguardStateController: KeyguardStateController
+
+ @Rule
+ @JvmField
+ var activityRule =
+ ActivityTestRule(
+ object :
+ SingleActivityFactory<TestableControlsActivity>(
+ TestableControlsActivity::class.java
+ ) {
+ override fun create(intent: Intent?): TestableControlsActivity {
+ return TestableControlsActivity(
+ uiController,
+ broadcastDispatcher,
+ dreamManager,
+ featureFlags,
+ controlsSettingsDialogManager,
+ keyguardStateController,
+ )
+ }
+ },
+ false,
+ false
+ )
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ activityRule.launchActivity(Intent())
+ }
+
+ @Test
+ fun testOrientationChangeForwardsToUiController() {
+ val currentConfig = activityRule.activity.resources.configuration
+ val newConfig = Configuration(currentConfig)
+ newConfig.orientation = switchOrientation(currentConfig.orientation)
+ activityRule.runOnUiThread { activityRule.activity.onConfigurationChanged(newConfig) }
+
+ verify(uiController).onSizeChange()
+ }
+
+ @Test
+ fun testScreenChangeForwardsToUiController() {
+ val currentConfig = activityRule.activity.resources.configuration
+ val newConfig = Configuration(currentConfig)
+ swapHeightWidth(newConfig)
+ activityRule.runOnUiThread { activityRule.activity.onConfigurationChanged(newConfig) }
+
+ verify(uiController).onSizeChange()
+ }
+
+ @Test
+ fun testChangeSmallestScreenSizeForwardsToUiController() {
+ val currentConfig = activityRule.activity.resources.configuration
+ val newConfig = Configuration(currentConfig)
+ newConfig.smallestScreenWidthDp *= 2
+ newConfig.screenWidthDp *= 2
+ activityRule.runOnUiThread { activityRule.activity.onConfigurationChanged(newConfig) }
+
+ verify(uiController).onSizeChange()
+ }
+
+ private fun switchOrientation(orientation: Int): Int {
+ return if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ Configuration.ORIENTATION_PORTRAIT
+ } else {
+ Configuration.ORIENTATION_LANDSCAPE
+ }
+ }
+
+ private fun swapHeightWidth(configuration: Configuration) {
+ val oldHeight = configuration.screenHeightDp
+ val oldWidth = configuration.screenWidthDp
+ configuration.screenHeightDp = oldWidth
+ configuration.screenWidthDp = oldHeight
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 5b3e518..330a1e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -470,7 +470,7 @@
taskViewConsumerCaptor.value.accept(taskView)
- underTest.onOrientationChange()
+ underTest.onSizeChange()
verify(taskView).onLocationChanged()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TestableControlsActivity.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TestableControlsActivity.kt
new file mode 100644
index 0000000..f0b4732
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TestableControlsActivity.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.controls.ui
+
+import android.service.dreams.IDreamManager
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.controls.settings.ControlsSettingsDialogManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.statusbar.policy.KeyguardStateController
+
+class TestableControlsActivity(
+ uiController: ControlsUiController,
+ broadcastDispatcher: BroadcastDispatcher,
+ dreamManager: IDreamManager,
+ featureFlags: FeatureFlags,
+ controlsSettingsDialogManager: ControlsSettingsDialogManager,
+ keyguardStateController: KeyguardStateController
+) :
+ ControlsActivity(
+ uiController,
+ broadcastDispatcher,
+ dreamManager,
+ featureFlags,
+ controlsSettingsDialogManager,
+ keyguardStateController
+ )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index a636b7f..b87647e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -408,6 +408,17 @@
}
@Test
+ public void testPulsing_dozeSuspendTriggers_pulseDone_doesntCrash() {
+ mMachine.requestState(INITIALIZED);
+
+ mMachine.requestState(DOZE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+ mMachine.requestState(DOZE_PULSING);
+ mMachine.requestState(DOZE_SUSPEND_TRIGGERS);
+ mMachine.requestState(DOZE_PULSE_DONE);
+ }
+
+ @Test
public void testSuppressingPulse_doesntCrash() {
mMachine.requestState(INITIALIZED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 0f25764..b88dbe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -32,6 +32,8 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -53,17 +55,21 @@
@Mock
Complication mComplication;
+ @Mock
+ private FeatureFlags mFeatureFlags;
+
final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
+
+ when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(false);
}
@Test
public void testStateChange_overlayActive() {
- final DreamOverlayStateController stateController = new DreamOverlayStateController(
- mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
stateController.setOverlayActive(true);
mExecutor.runAllReady();
@@ -84,8 +90,7 @@
@Test
public void testCallback() {
- final DreamOverlayStateController stateController = new DreamOverlayStateController(
- mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
// Add complication and verify callback is notified.
@@ -110,8 +115,7 @@
@Test
public void testNotifyOnCallbackAdd() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addComplication(mComplication);
mExecutor.runAllReady();
@@ -124,8 +128,7 @@
@Test
public void testNotifyOnCallbackAddOverlayDisabled() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, false);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(false);
stateController.addComplication(mComplication);
mExecutor.runAllReady();
@@ -139,8 +142,7 @@
@Test
public void testComplicationFilteringWhenShouldShowComplications() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.setShouldShowComplications(true);
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -179,8 +181,7 @@
@Test
public void testComplicationFilteringWhenShouldHideComplications() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.setShouldShowComplications(true);
final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
@@ -226,8 +227,7 @@
@Test
public void testComplicationWithNoTypeNotFiltered() {
final Complication complication = Mockito.mock(Complication.class);
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addComplication(complication);
mExecutor.runAllReady();
assertThat(stateController.getComplications(true).contains(complication))
@@ -236,8 +236,7 @@
@Test
public void testNotifyLowLightChanged() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -252,8 +251,7 @@
@Test
public void testNotifyLowLightExit() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -276,8 +274,7 @@
@Test
public void testNotifyEntryAnimationsFinishedChanged() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -292,8 +289,7 @@
@Test
public void testNotifyDreamOverlayStatusBarVisibleChanged() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -308,8 +304,7 @@
@Test
public void testNotifyHasAssistantAttentionChanged() {
- final DreamOverlayStateController stateController =
- new DreamOverlayStateController(mExecutor, true);
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
@@ -321,4 +316,50 @@
verify(mCallback, times(1)).onStateChanged();
assertThat(stateController.hasAssistantAttention()).isTrue();
}
+
+ @Test
+ public void testShouldShowComplicationsSetToFalse_stillShowsHomeControls_featureEnabled() {
+ when(mFeatureFlags.isEnabled(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS)).thenReturn(true);
+
+ final DreamOverlayStateController stateController = getDreamOverlayStateController(true);
+ stateController.setShouldShowComplications(true);
+
+ final Complication homeControlsComplication = Mockito.mock(Complication.class);
+ when(homeControlsComplication.getRequiredTypeAvailability())
+ .thenReturn(Complication.COMPLICATION_TYPE_HOME_CONTROLS);
+
+ stateController.addComplication(homeControlsComplication);
+
+ final DreamOverlayStateController.Callback callback =
+ Mockito.mock(DreamOverlayStateController.Callback.class);
+
+ stateController.setAvailableComplicationTypes(
+ Complication.COMPLICATION_TYPE_HOME_CONTROLS);
+ stateController.addCallback(callback);
+ mExecutor.runAllReady();
+
+ {
+ clearInvocations(callback);
+ stateController.setShouldShowComplications(true);
+ mExecutor.runAllReady();
+
+ verify(callback).onAvailableComplicationTypesChanged();
+ final Collection<Complication> complications = stateController.getComplications();
+ assertThat(complications.contains(homeControlsComplication)).isTrue();
+ }
+
+ {
+ clearInvocations(callback);
+ stateController.setShouldShowComplications(false);
+ mExecutor.runAllReady();
+
+ verify(callback).onAvailableComplicationTypesChanged();
+ final Collection<Complication> complications = stateController.getComplications();
+ assertThat(complications.contains(homeControlsComplication)).isTrue();
+ }
+ }
+
+ private DreamOverlayStateController getDreamOverlayStateController(boolean overlayEnabled) {
+ return new DreamOverlayStateController(mExecutor, overlayEnabled, mFeatureFlags);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index d6dbd73..1a89076 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -31,7 +31,6 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.testing.AndroidTestingRunner;
-import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
@@ -101,20 +100,16 @@
@Mock
UiEventLogger mUiEventLogger;
- final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
-
private static final float TOUCH_REGION = .3f;
private static final int SCREEN_WIDTH_PX = 1024;
private static final int SCREEN_HEIGHT_PX = 100;
+ private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
+
@Before
public void setup() {
- mDisplayMetrics.widthPixels = SCREEN_WIDTH_PX;
- mDisplayMetrics.heightPixels = SCREEN_HEIGHT_PX;
-
MockitoAnnotations.initMocks(this);
mTouchHandler = new BouncerSwipeTouchHandler(
- mDisplayMetrics,
mScrimManager,
Optional.of(mCentralSurfaces),
mNotificationShadeWindowController,
@@ -127,10 +122,10 @@
when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
when(mCentralSurfaces.isBouncerShowing()).thenReturn(false);
- when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX);
when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
when(mVelocityTrackerFactory.obtain()).thenReturn(mVelocityTracker);
when(mFlingAnimationUtils.getMinVelocityPxPerSecond()).thenReturn(Float.MAX_VALUE);
+ when(mTouchSession.getBounds()).thenReturn(SCREEN_BOUNDS);
}
/**
@@ -139,7 +134,7 @@
@Test
public void testSessionStart() {
final Region region = Region.obtain();
- mTouchHandler.getTouchInitiationRegion(region);
+ mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, region);
final Rect bounds = region.getBounds();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
index 178b9cc..7f6e2ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
@@ -20,6 +20,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
@@ -44,6 +45,7 @@
import com.android.systemui.dreams.touch.dagger.InputSessionComponent;
import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.display.DisplayHelper;
import com.android.systemui.util.time.FakeSystemClock;
import com.google.common.util.concurrent.ListenableFuture;
@@ -79,7 +81,9 @@
private final DefaultLifecycleObserver mLifecycleObserver;
private final InputChannelCompat.InputEventListener mEventListener;
private final GestureDetector.OnGestureListener mGestureListener;
+ private final DisplayHelper mDisplayHelper;
private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+ private final Rect mDisplayBounds = Mockito.mock(Rect.class);
Environment(Set<DreamTouchHandler> handlers) {
mLifecycle = Mockito.mock(Lifecycle.class);
@@ -93,7 +97,11 @@
.thenReturn(inputComponent);
when(inputComponent.getInputSession()).thenReturn(mInputSession);
- mMonitor = new DreamOverlayTouchMonitor(mExecutor, mLifecycle, mInputFactory, handlers);
+ mDisplayHelper = Mockito.mock(DisplayHelper.class);
+ when(mDisplayHelper.getMaxBounds(anyInt(), anyInt()))
+ .thenReturn(mDisplayBounds);
+ mMonitor = new DreamOverlayTouchMonitor(mExecutor, mLifecycle, mInputFactory,
+ mDisplayHelper, handlers);
mMonitor.init();
final ArgumentCaptor<LifecycleObserver> lifecycleObserverCaptor =
@@ -117,6 +125,10 @@
mGestureListener = gestureListenerCaptor.getValue();
}
+ public Rect getDisplayBounds() {
+ return mDisplayBounds;
+ }
+
void executeAll() {
mExecutor.runAllReady();
}
@@ -140,15 +152,37 @@
}
@Test
+ public void testReportedDisplayBounds() {
+ final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+ final Environment environment = new Environment(Stream.of(touchHandler)
+ .collect(Collectors.toCollection(HashSet::new)));
+
+ final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+ when(initialEvent.getX()).thenReturn(0.0f);
+ when(initialEvent.getY()).thenReturn(0.0f);
+ environment.publishInputEvent(initialEvent);
+
+ // Verify display bounds passed into TouchHandler#getTouchInitiationRegion
+ verify(touchHandler).getTouchInitiationRegion(eq(environment.getDisplayBounds()), any());
+ final ArgumentCaptor<DreamTouchHandler.TouchSession> touchSessionArgumentCaptor =
+ ArgumentCaptor.forClass(DreamTouchHandler.TouchSession.class);
+ verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
+
+ // Verify that display bounds provided from TouchSession#getBounds
+ assertThat(touchSessionArgumentCaptor.getValue().getBounds())
+ .isEqualTo(environment.getDisplayBounds());
+ }
+
+ @Test
public void testEntryTouchZone() {
final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
final Rect touchArea = new Rect(4, 4, 8 , 8);
doAnswer(invocation -> {
- final Region region = (Region) invocation.getArguments()[0];
+ final Region region = (Region) invocation.getArguments()[1];
region.set(touchArea);
return null;
- }).when(touchHandler).getTouchInitiationRegion(any());
+ }).when(touchHandler).getTouchInitiationRegion(any(), any());
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
@@ -174,10 +208,10 @@
final DreamTouchHandler unzonedTouchHandler = Mockito.mock(DreamTouchHandler.class);
doAnswer(invocation -> {
- final Region region = (Region) invocation.getArguments()[0];
+ final Region region = (Region) invocation.getArguments()[1];
region.set(touchArea);
return null;
- }).when(touchHandler).getTouchInitiationRegion(any());
+ }).when(touchHandler).getTouchInitiationRegion(any(), any());
final Environment environment = new Environment(Stream.of(touchHandler, unzonedTouchHandler)
.collect(Collectors.toCollection(HashSet::new)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
index 2db4596..e287f19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
@@ -21,12 +21,15 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.never
@@ -58,36 +61,37 @@
}
@Test
- fun testStoreDreamState_onDreamingStarted() {
- listener.onDreamingChanged(true)
+ fun testStoreDreamState_onDozingStarted() {
+ listener.onDozingChanged(true)
executor.runAllReady()
- assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue()
+ assertThat(settings.getBool(RestartDozeListener.RESTART_SLEEP_KEY)).isTrue()
}
@Test
- fun testStoreDreamState_onDreamingStopped() {
- listener.onDreamingChanged(false)
+ fun testStoreDozeState_onDozingStopped() {
+ listener.onDozingChanged(false)
executor.runAllReady()
- assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse()
+ assertThat(settings.getBool(RestartDozeListener.RESTART_SLEEP_KEY)).isFalse()
}
@Test
- fun testRestoreDreamState_dreamingShouldStart() {
- settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true)
+ fun testRestoreDozeState_dozingShouldStart() {
+ settings.putBool(RestartDozeListener.RESTART_SLEEP_KEY, true)
restartDozeListener.maybeRestartSleep()
executor.advanceClockToLast()
executor.runAllReady()
- verify(powerManager).wakeUp(clock.uptimeMillis())
+ verify(powerManager)
+ .wakeUp(eq(clock.uptimeMillis()), eq(PowerManager.WAKE_REASON_APPLICATION), anyString())
verify(powerManager).goToSleep(clock.uptimeMillis())
}
@Test
- fun testRestoreDreamState_dreamingShouldNot() {
- settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false)
+ fun testRestoreDozeState_dozingShouldNotStart() {
+ settings.putBool(RestartDozeListener.RESTART_SLEEP_KEY, false)
restartDozeListener.maybeRestartSleep()
executor.advanceClockToLast()
executor.runAllReady()
- verify(powerManager, never()).wakeUp(anyLong())
+ verify(powerManager, never()).wakeUp(anyLong(), anyInt(), anyString())
verify(powerManager, never()).goToSleep(anyLong())
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index 5ec6283..bdc33f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -39,6 +39,7 @@
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.utils.os.FakeHandler
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -50,7 +51,6 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -90,9 +90,9 @@
keyguardUpdateMonitor,
keyguardBypassController,
)
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
- `when`(repository.primaryBouncerShow.value).thenReturn(false)
- `when`(bouncerView.delegate).thenReturn(bouncerViewDelegate)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
+ whenever(repository.primaryBouncerShow.value).thenReturn(false)
+ whenever(bouncerView.delegate).thenReturn(bouncerViewDelegate)
resources = context.orCreateTestableResources
}
@@ -118,7 +118,7 @@
@Test
fun testShow_keyguardIsDone() {
- `when`(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true)
+ whenever(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true)
verify(keyguardStateController, never()).notifyPrimaryBouncerShowing(true)
verify(mPrimaryBouncerCallbackInteractor, never()).dispatchStartingToShow()
}
@@ -135,7 +135,7 @@
@Test
fun testExpansion() {
- `when`(repository.panelExpansionAmount.value).thenReturn(0.5f)
+ whenever(repository.panelExpansionAmount.value).thenReturn(0.5f)
underTest.setPanelExpansion(0.6f)
verify(repository).setPanelExpansion(0.6f)
verify(mPrimaryBouncerCallbackInteractor).dispatchExpansionChanged(0.6f)
@@ -143,8 +143,8 @@
@Test
fun testExpansion_fullyShown() {
- `when`(repository.panelExpansionAmount.value).thenReturn(0.5f)
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
+ whenever(repository.panelExpansionAmount.value).thenReturn(0.5f)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
underTest.setPanelExpansion(EXPANSION_VISIBLE)
verify(falsingCollector).onBouncerShown()
verify(mPrimaryBouncerCallbackInteractor).dispatchFullyShown()
@@ -152,8 +152,8 @@
@Test
fun testExpansion_fullyHidden() {
- `when`(repository.panelExpansionAmount.value).thenReturn(0.5f)
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
+ whenever(repository.panelExpansionAmount.value).thenReturn(0.5f)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
underTest.setPanelExpansion(EXPANSION_HIDDEN)
verify(repository).setPrimaryShow(false)
verify(falsingCollector).onBouncerHidden()
@@ -163,7 +163,7 @@
@Test
fun testExpansion_startingToHide() {
- `when`(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE)
+ whenever(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE)
underTest.setPanelExpansion(0.1f)
verify(repository).setPrimaryStartingToHide(true)
verify(mPrimaryBouncerCallbackInteractor).dispatchStartingToHide()
@@ -228,7 +228,21 @@
}
@Test
- fun testStartDisappearAnimation() {
+ fun testStartDisappearAnimation_willRunDismissFromKeyguard() {
+ whenever(bouncerViewDelegate.willRunDismissFromKeyguard()).thenReturn(true)
+
+ val runnable = mock(Runnable::class.java)
+ underTest.startDisappearAnimation(runnable)
+ // End runnable should run immediately
+ verify(runnable).run()
+ // ... while the disappear animation should never be run
+ verify(repository, never()).setPrimaryStartDisappearAnimation(any(Runnable::class.java))
+ }
+
+ @Test
+ fun testStartDisappearAnimation_willNotRunDismissFromKeyguard_() {
+ whenever(bouncerViewDelegate.willRunDismissFromKeyguard()).thenReturn(false)
+
val runnable = mock(Runnable::class.java)
underTest.startDisappearAnimation(runnable)
verify(repository).setPrimaryStartDisappearAnimation(any(Runnable::class.java))
@@ -236,45 +250,45 @@
@Test
fun testIsFullShowing() {
- `when`(repository.primaryBouncerShow.value).thenReturn(true)
- `when`(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE)
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
+ whenever(repository.primaryBouncerShow.value).thenReturn(true)
+ whenever(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
assertThat(underTest.isFullyShowing()).isTrue()
- `when`(repository.primaryBouncerShow.value).thenReturn(false)
+ whenever(repository.primaryBouncerShow.value).thenReturn(false)
assertThat(underTest.isFullyShowing()).isFalse()
}
@Test
fun testIsScrimmed() {
- `when`(repository.primaryBouncerScrimmed.value).thenReturn(true)
+ whenever(repository.primaryBouncerScrimmed.value).thenReturn(true)
assertThat(underTest.isScrimmed()).isTrue()
- `when`(repository.primaryBouncerScrimmed.value).thenReturn(false)
+ whenever(repository.primaryBouncerScrimmed.value).thenReturn(false)
assertThat(underTest.isScrimmed()).isFalse()
}
@Test
fun testIsInTransit() {
- `when`(repository.primaryBouncerShowingSoon.value).thenReturn(true)
+ whenever(repository.primaryBouncerShowingSoon.value).thenReturn(true)
assertThat(underTest.isInTransit()).isTrue()
- `when`(repository.primaryBouncerShowingSoon.value).thenReturn(false)
+ whenever(repository.primaryBouncerShowingSoon.value).thenReturn(false)
assertThat(underTest.isInTransit()).isFalse()
- `when`(repository.panelExpansionAmount.value).thenReturn(0.5f)
+ whenever(repository.panelExpansionAmount.value).thenReturn(0.5f)
assertThat(underTest.isInTransit()).isTrue()
}
@Test
fun testIsAnimatingAway() {
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(Runnable {})
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(Runnable {})
assertThat(underTest.isAnimatingAway()).isTrue()
- `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
assertThat(underTest.isAnimatingAway()).isFalse()
}
@Test
fun testWillDismissWithAction() {
- `when`(bouncerViewDelegate.willDismissWithActions()).thenReturn(true)
+ whenever(bouncerViewDelegate.willDismissWithActions()).thenReturn(true)
assertThat(underTest.willDismissWithAction()).isTrue()
- `when`(bouncerViewDelegate.willDismissWithActions()).thenReturn(false)
+ whenever(bouncerViewDelegate.willDismissWithActions()).thenReturn(false)
assertThat(underTest.willDismissWithAction()).isFalse()
}
@@ -363,12 +377,13 @@
isUnlockingWithFpAllowed: Boolean,
isAnimatingAway: Boolean
) {
- `when`(repository.primaryBouncerShow.value).thenReturn(isVisible)
+ whenever(repository.primaryBouncerShow.value).thenReturn(isVisible)
resources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer, sfpsEnabled)
- `when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(fpsDetectionRunning)
- `when`(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
+ whenever(keyguardUpdateMonitor.isFingerprintDetectionRunning)
+ .thenReturn(fpsDetectionRunning)
+ whenever(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
.thenReturn(isUnlockingWithFpAllowed)
- `when`(repository.primaryBouncerStartingDisappearAnimation.value)
+ whenever(repository.primaryBouncerStartingDisappearAnimation.value)
.thenReturn(if (isAnimatingAway) Runnable {} else null)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index 746f668..98794fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -115,7 +115,7 @@
repository.sendTransitionStep(step(1f))
assertThat(values.size).isEqualTo(4)
- values.forEach { assertThat(it).isEqualTo(ScrimAlpha(notificationsAlpha = 1f)) }
+ values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) }
job.cancel()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index e0ca90e..a72634b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.media.controls.ui
import android.app.PendingIntent
-import android.content.res.ColorStateList
+import android.content.res.Configuration
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.util.MathUtils.abs
@@ -26,9 +26,9 @@
import com.android.internal.logging.InstanceId
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -49,7 +49,7 @@
import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
@@ -89,6 +89,7 @@
@Mock lateinit var mediaHostStatesManager: MediaHostStatesManager
@Mock lateinit var mediaHostState: MediaHostState
@Mock lateinit var activityStarter: ActivityStarter
+ @Mock @Main private lateinit var executor: DelayableExecutor
@Mock lateinit var mediaDataManager: MediaDataManager
@Mock lateinit var configurationController: ConfigurationController
@Mock lateinit var falsingCollector: FalsingCollector
@@ -112,15 +113,11 @@
private val clock = FakeSystemClock()
private lateinit var mediaCarouselController: MediaCarouselController
- private lateinit var mainExecutor: FakeExecutor
- private lateinit var backgroundExecutor: FakeExecutor
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
transitionRepository = FakeKeyguardTransitionRepository()
- mainExecutor = FakeExecutor(clock)
- backgroundExecutor = FakeExecutor(clock)
mediaCarouselController =
MediaCarouselController(
context,
@@ -129,8 +126,7 @@
mediaHostStatesManager,
activityStarter,
clock,
- mainExecutor,
- backgroundExecutor,
+ executor,
mediaDataManager,
configurationController,
falsingCollector,
@@ -405,7 +401,6 @@
resumption = true
)
)
- runAllReady()
assertEquals(
MediaPlayerData.getMediaPlayerIndex("paused local"),
@@ -515,8 +510,6 @@
false
)
mediaCarouselController.shouldScrollToKey = true
- runAllReady()
-
// switching between media players.
listener.value.onMediaDataLoaded(
"playing local",
@@ -538,7 +531,6 @@
resumption = false
)
)
- runAllReady()
assertEquals(
MediaPlayerData.getMediaPlayerIndex("paused local"),
@@ -563,7 +555,6 @@
resumption = false
)
)
- runAllReady()
var playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
assertEquals(
@@ -586,8 +577,6 @@
packageName = "PACKAGE_NAME"
)
)
- runAllReady()
-
playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
assertEquals(playerIndex, 0)
}
@@ -684,9 +673,17 @@
}
@Test
- fun testOnUiModeChanged_playersAreAddedBack() {
- mediaCarouselController.pageIndicator = pageIndicator
-
+ fun testOnConfigChanged_playersAreAddedBack() {
+ listener.value.onMediaDataLoaded(
+ "playing local",
+ null,
+ DATA.copy(
+ active = true,
+ isPlaying = true,
+ playbackLocation = MediaData.PLAYBACK_LOCAL,
+ resumption = false
+ )
+ )
listener.value.onMediaDataLoaded(
"paused local",
null,
@@ -697,75 +694,14 @@
resumption = false
)
)
- runAllReady()
val playersSize = MediaPlayerData.players().size
- configListener.value.onUiModeChanged()
- runAllReady()
- verify(pageIndicator).tintList =
- ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ configListener.value.onConfigChanged(Configuration())
+
assertEquals(playersSize, MediaPlayerData.players().size)
assertEquals(
- MediaPlayerData.getMediaPlayerIndex("paused local"),
- mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
- )
- }
-
- @Test
- fun testOnDensityOrFontScaleChanged_playersAreAddedBack() {
- mediaCarouselController.pageIndicator = pageIndicator
-
- listener.value.onMediaDataLoaded(
- "paused local",
- null,
- DATA.copy(
- active = true,
- isPlaying = false,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false
- )
- )
- runAllReady()
-
- val playersSize = MediaPlayerData.players().size
- configListener.value.onDensityOrFontScaleChanged()
- runAllReady()
-
- verify(pageIndicator).tintList =
- ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
- assertEquals(playersSize, MediaPlayerData.players().size)
- assertEquals(
- MediaPlayerData.getMediaPlayerIndex("paused local"),
- mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
- )
- }
-
- @Test
- fun testOnThemeChanged_playersAreAddedBack() {
- mediaCarouselController.pageIndicator = pageIndicator
-
- listener.value.onMediaDataLoaded(
- "paused local",
- null,
- DATA.copy(
- active = true,
- isPlaying = false,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false
- )
- )
- runAllReady()
-
- val playersSize = MediaPlayerData.players().size
- configListener.value.onThemeChanged()
- runAllReady()
-
- verify(pageIndicator).tintList =
- ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
- assertEquals(playersSize, MediaPlayerData.players().size)
- assertEquals(
- MediaPlayerData.getMediaPlayerIndex("paused local"),
+ MediaPlayerData.getMediaPlayerIndex("playing local"),
mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
)
}
@@ -896,9 +832,4 @@
// Verify that seekbar listening attribute in media control panel is set to false.
verify(panel, times(MediaPlayerData.players().size)).listening = false
}
-
- private fun runAllReady() {
- backgroundExecutor.runAllReady()
- mainExecutor.runAllReady()
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index 55b57f1..543875d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -209,12 +209,6 @@
@Mock private lateinit var coverContainer3: ViewGroup
@Mock private lateinit var recAppIconItem: CachingIconView
@Mock private lateinit var recCardTitle: TextView
- @Mock private lateinit var recProgressBar1: SeekBar
- @Mock private lateinit var recProgressBar2: SeekBar
- @Mock private lateinit var recProgressBar3: SeekBar
- @Mock private lateinit var recSubtitleMock1: TextView
- @Mock private lateinit var recSubtitleMock2: TextView
- @Mock private lateinit var recSubtitleMock3: TextView
@Mock private lateinit var coverItem: ImageView
@Mock private lateinit var matrix: Matrix
private lateinit var coverItem1: ImageView
@@ -226,6 +220,9 @@
private lateinit var recSubtitle1: TextView
private lateinit var recSubtitle2: TextView
private lateinit var recSubtitle3: TextView
+ @Mock private lateinit var recProgressBar1: SeekBar
+ @Mock private lateinit var recProgressBar2: SeekBar
+ @Mock private lateinit var recProgressBar3: SeekBar
private var shouldShowBroadcastButton: Boolean = false
private val fakeFeatureFlag =
FakeFeatureFlags().apply {
@@ -636,10 +633,7 @@
@Test
fun bindAlbumView_setAfterExecutors() {
- val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val canvas = Canvas(bmp)
- canvas.drawColor(Color.RED)
- val albumArt = Icon.createWithBitmap(bmp)
+ val albumArt = getColorIcon(Color.RED)
val state = mediaData.copy(artwork = albumArt)
player.attachPlayer(viewHolder)
@@ -652,15 +646,8 @@
@Test
fun bindAlbumView_bitmapInLaterStates_setAfterExecutors() {
- val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val redCanvas = Canvas(redBmp)
- redCanvas.drawColor(Color.RED)
- val redArt = Icon.createWithBitmap(redBmp)
-
- val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val greenCanvas = Canvas(greenBmp)
- greenCanvas.drawColor(Color.GREEN)
- val greenArt = Icon.createWithBitmap(greenBmp)
+ val redArt = getColorIcon(Color.RED)
+ val greenArt = getColorIcon(Color.GREEN)
val state0 = mediaData.copy(artwork = null)
val state1 = mediaData.copy(artwork = redArt)
@@ -705,18 +692,12 @@
@Test
fun addTwoPlayerGradients_differentStates() {
// Setup redArtwork and its color scheme.
- val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val redCanvas = Canvas(redBmp)
- redCanvas.drawColor(Color.RED)
- val redArt = Icon.createWithBitmap(redBmp)
+ val redArt = getColorIcon(Color.RED)
val redWallpaperColor = player.getWallpaperColor(redArt)
val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)
// Setup greenArt and its color scheme.
- val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val greenCanvas = Canvas(greenBmp)
- greenCanvas.drawColor(Color.GREEN)
- val greenArt = Icon.createWithBitmap(greenBmp)
+ val greenArt = getColorIcon(Color.GREEN)
val greenWallpaperColor = player.getWallpaperColor(greenArt)
val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)
@@ -2040,12 +2021,12 @@
.setExtras(Bundle.EMPTY)
.build(),
SmartspaceAction.Builder("id2", "title2")
- .setSubtitle("")
+ .setSubtitle("subtitle2")
.setIcon(icon)
.setExtras(Bundle.EMPTY)
.build(),
SmartspaceAction.Builder("id3", "title3")
- .setSubtitle("subtitle3")
+ .setSubtitle("")
.setIcon(icon)
.setExtras(Bundle.EMPTY)
.build()
@@ -2125,26 +2106,18 @@
assertThat(expandedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
assertThat(expandedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
assertThat(expandedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recTitle1.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recTitle2.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recTitle3.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recSubtitle1.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recSubtitle2.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(recSubtitle3.id)).isEqualTo(ConstraintSet.GONE)
}
@Test
fun bindRecommendation_setAfterExecutors() {
- fakeFeatureFlag.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, true)
- whenever(recommendationViewHolder.mediaAppIcons)
- .thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem))
- whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
- whenever(recommendationViewHolder.mediaCoverItems)
- .thenReturn(listOf(coverItem, coverItem, coverItem))
- whenever(recommendationViewHolder.mediaProgressBars)
- .thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
- whenever(recommendationViewHolder.mediaSubtitles)
- .thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
- whenever(coverItem.imageMatrix).thenReturn(matrix)
-
- val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val canvas = Canvas(bmp)
- canvas.drawColor(Color.RED)
- val albumArt = Icon.createWithBitmap(bmp)
+ setupUpdatedRecommendationViewHolder()
+ val albumArt = getColorIcon(Color.RED)
val data =
smartspaceData.copy(
recommendations =
@@ -2180,21 +2153,9 @@
@Test
fun bindRecommendationWithProgressBars() {
- fakeFeatureFlag.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, true)
- whenever(recommendationViewHolder.mediaAppIcons)
- .thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem))
- whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
- whenever(recommendationViewHolder.mediaCoverItems)
- .thenReturn(listOf(coverItem, coverItem, coverItem))
- whenever(recommendationViewHolder.mediaProgressBars)
- .thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
- whenever(recommendationViewHolder.mediaSubtitles)
- .thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
-
- val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val canvas = Canvas(bmp)
- canvas.drawColor(Color.RED)
- val albumArt = Icon.createWithBitmap(bmp)
+ useRealConstraintSets()
+ setupUpdatedRecommendationViewHolder()
+ val albumArt = getColorIcon(Color.RED)
val bundle =
Bundle().apply {
putInt(
@@ -2232,26 +2193,61 @@
verify(recProgressBar1).visibility = View.VISIBLE
verify(recProgressBar2).visibility = View.GONE
verify(recProgressBar3).visibility = View.GONE
- verify(recSubtitleMock1).visibility = View.GONE
- verify(recSubtitleMock2).visibility = View.VISIBLE
- verify(recSubtitleMock3).visibility = View.VISIBLE
+ assertThat(recSubtitle1.visibility).isEqualTo(View.GONE)
+ assertThat(recSubtitle2.visibility).isEqualTo(View.VISIBLE)
+ assertThat(recSubtitle3.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @Test
+ fun bindRecommendation_carouselNotFitThreeRecs() {
+ useRealConstraintSets()
+ setupUpdatedRecommendationViewHolder()
+ val albumArt = getColorIcon(Color.RED)
+ val data =
+ smartspaceData.copy(
+ recommendations =
+ listOf(
+ SmartspaceAction.Builder("id1", "title1")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", "title2")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", "title3")
+ .setSubtitle("subtitle1")
+ .setIcon(albumArt)
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+
+ // set the screen width less than the width of media controls.
+ player.context.resources.configuration.screenWidthDp = 350
+ player.attachRecommendation(recommendationViewHolder)
+ player.bindRecommendation(data)
+
+ assertThat(player.numberOfFittedRecommendations).isEqualTo(2)
+ assertThat(expandedSet.getVisibility(coverContainer1.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(collapsedSet.getVisibility(coverContainer1.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(coverContainer2.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(collapsedSet.getVisibility(coverContainer2.id)).isEqualTo(ConstraintSet.VISIBLE)
+ assertThat(expandedSet.getVisibility(coverContainer3.id)).isEqualTo(ConstraintSet.GONE)
+ assertThat(collapsedSet.getVisibility(coverContainer3.id)).isEqualTo(ConstraintSet.GONE)
}
@Test
fun addTwoRecommendationGradients_differentStates() {
// Setup redArtwork and its color scheme.
- val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val redCanvas = Canvas(redBmp)
- redCanvas.drawColor(Color.RED)
- val redArt = Icon.createWithBitmap(redBmp)
+ val redArt = getColorIcon(Color.RED)
val redWallpaperColor = player.getWallpaperColor(redArt)
val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)
// Setup greenArt and its color scheme.
- val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
- val greenCanvas = Canvas(greenBmp)
- greenCanvas.drawColor(Color.GREEN)
- val greenArt = Icon.createWithBitmap(greenBmp)
+ val greenArt = getColorIcon(Color.GREEN)
val greenWallpaperColor = player.getWallpaperColor(greenArt)
val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)
@@ -2392,6 +2388,34 @@
verify(activityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent))
}
+ private fun setupUpdatedRecommendationViewHolder() {
+ fakeFeatureFlag.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, true)
+ whenever(recommendationViewHolder.mediaAppIcons)
+ .thenReturn(listOf(recAppIconItem, recAppIconItem, recAppIconItem))
+ whenever(recommendationViewHolder.cardTitle).thenReturn(recCardTitle)
+ whenever(recommendationViewHolder.mediaCoverContainers)
+ .thenReturn(listOf(coverContainer1, coverContainer2, coverContainer3))
+ whenever(recommendationViewHolder.mediaCoverItems)
+ .thenReturn(listOf(coverItem, coverItem, coverItem))
+ whenever(recommendationViewHolder.mediaProgressBars)
+ .thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
+ whenever(recommendationViewHolder.mediaSubtitles)
+ .thenReturn(listOf(recSubtitle1, recSubtitle2, recSubtitle3))
+ whenever(coverItem.imageMatrix).thenReturn(matrix)
+
+ // set ids for recommendation containers
+ whenever(coverContainer1.id).thenReturn(1)
+ whenever(coverContainer2.id).thenReturn(2)
+ whenever(coverContainer3.id).thenReturn(3)
+ }
+
+ private fun getColorIcon(color: Int): Icon {
+ val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bmp)
+ canvas.drawColor(color)
+ return Icon.createWithBitmap(bmp)
+ }
+
private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
withArgCaptor {
verify(seekBarViewModel).setScrubbingChangeListener(capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
index 3d5dba3..e2cf87a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogReceiverTest.java
@@ -92,7 +92,7 @@
verify(mMockMediaOutputDialogFactory, never()).create(any(), anyBoolean(), any());
verify(mMockMediaOutputBroadcastDialogFactory, times(1))
- .create(getContext().getPackageName(), false, null);
+ .create(getContext().getPackageName(), true, null);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
index 464acb6..01ffdcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
@@ -19,12 +19,14 @@
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
+import android.graphics.Insets
import android.graphics.Rect
import android.util.DisplayMetrics.DENSITY_DEFAULT
+import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowMetrics
+import androidx.core.view.WindowInsetsCompat.Type
import androidx.test.filters.SmallTest
-import com.android.internal.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider.TaskPreviewSizeListener
import com.android.systemui.statusbar.policy.FakeConfigurationController
@@ -94,7 +96,13 @@
}
private fun givenTaskbarSize(size: Int) {
- whenever(resources.getDimensionPixelSize(eq(R.dimen.taskbar_frame_height))).thenReturn(size)
+ val windowInsets =
+ WindowInsets.Builder()
+ .setInsets(Type.tappableElement(), Insets.of(Rect(0, 0, 0, size)))
+ .build()
+ val windowMetrics = WindowMetrics(windowManager.maximumWindowMetrics.bounds, windowInsets)
+ whenever(windowManager.maximumWindowMetrics).thenReturn(windowMetrics)
+ whenever(windowManager.currentWindowMetrics).thenReturn(windowMetrics)
}
private fun givenDisplay(width: Int, height: Int, isTablet: Boolean = false) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 0ee52ea..e640946 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -13,10 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@file:OptIn(InternalNoteTaskApi::class)
+
package com.android.systemui.notetask
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
+import android.app.role.RoleManager
+import android.app.role.RoleManager.ROLE_NOTES
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -24,12 +28,20 @@
import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+import android.content.pm.ShortcutInfo
+import android.content.pm.ShortcutManager
import android.os.UserHandle
import android.os.UserManager
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
+import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
+import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.any
@@ -47,6 +59,7 @@
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.isNull
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@@ -63,15 +76,17 @@
@Mock lateinit var keyguardManager: KeyguardManager
@Mock lateinit var userManager: UserManager
@Mock lateinit var eventLogger: NoteTaskEventLogger
+ @Mock lateinit var roleManager: RoleManager
+ @Mock lateinit var shortcutManager: ShortcutManager
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
private val userTracker: UserTracker = FakeUserTracker()
-
private val noteTaskInfo = NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID)
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ whenever(context.getString(R.string.note_task_button_label)).thenReturn(NOTES_SHORT_LABEL)
whenever(context.packageManager).thenReturn(packageManager)
whenever(resolver.resolveInfo(any(), any())).thenReturn(noteTaskInfo)
whenever(userManager.isUserUnlocked).thenReturn(true)
@@ -82,6 +97,8 @@
)
)
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE)
+ whenever(roleManager.getRoleHoldersAsUser(ROLE_NOTES, userTracker.userHandle))
+ .thenReturn(listOf(NOTES_PACKAGE_NAME))
}
private fun createNoteTaskController(
@@ -98,6 +115,8 @@
isEnabled = isEnabled,
devicePolicyManager = devicePolicyManager,
userTracker = userTracker,
+ roleManager = roleManager,
+ shortcutManager = shortcutManager,
)
// region onBubbleExpandChanged
@@ -132,7 +151,7 @@
}
@Test
- fun onBubbleExpandChanged_expandingAndKeyguardLocked_doNothing() {
+ fun onBubbleExpandChanged_expandingAndKeyguardLocked_shouldDoNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true)
createNoteTaskController()
@@ -146,7 +165,7 @@
}
@Test
- fun onBubbleExpandChanged_notExpandingAndKeyguardLocked_doNothing() {
+ fun onBubbleExpandChanged_notExpandingAndKeyguardLocked_shouldDoNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true)
createNoteTaskController()
@@ -268,8 +287,8 @@
verifyZeroInteractions(context)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
- isNull())
+ verify(bubbles)
+ .showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle), isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -333,11 +352,11 @@
verify(context.packageManager)
.setComponentEnabledSetting(
argument.capture(),
- eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+ eq(COMPONENT_ENABLED_STATE_ENABLED),
eq(PackageManager.DONT_KILL_APP),
)
- val expected = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
- assertThat(argument.value.flattenToString()).isEqualTo(expected.flattenToString())
+ assertThat(argument.value.className)
+ .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
@Test
@@ -348,11 +367,11 @@
verify(context.packageManager)
.setComponentEnabledSetting(
argument.capture(),
- eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
+ eq(COMPONENT_ENABLED_STATE_DISABLED),
eq(PackageManager.DONT_KILL_APP),
)
- val expected = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
- assertThat(argument.value.flattenToString()).isEqualTo(expected.flattenToString())
+ assertThat(argument.value.className)
+ .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
// endregion
@@ -403,8 +422,8 @@
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
- isNull())
+ verify(bubbles)
+ .showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle), isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -427,8 +446,8 @@
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
- isNull())
+ verify(bubbles)
+ .showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle), isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -438,7 +457,78 @@
}
// endregion
+ // region updateNoteTaskAsUser
+ @Test
+ fun updateNoteTaskAsUser_withNotesRole_withShortcuts_shouldUpdateShortcuts() {
+ createNoteTaskController(isEnabled = true).updateNoteTaskAsUser(userTracker.userHandle)
+
+ val actualComponent = argumentCaptor<ComponentName>()
+ verify(context.packageManager)
+ .setComponentEnabledSetting(
+ actualComponent.capture(),
+ eq(COMPONENT_ENABLED_STATE_ENABLED),
+ eq(PackageManager.DONT_KILL_APP),
+ )
+ assertThat(actualComponent.value.className)
+ .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+ verify(shortcutManager, never()).disableShortcuts(any())
+ verify(shortcutManager).enableShortcuts(listOf(SHORTCUT_ID))
+ val actualShortcuts = argumentCaptor<List<ShortcutInfo>>()
+ verify(shortcutManager).updateShortcuts(actualShortcuts.capture())
+ val actualShortcut = actualShortcuts.value.first()
+ assertThat(actualShortcut.id).isEqualTo(SHORTCUT_ID)
+ assertThat(actualShortcut.intent?.component?.className)
+ .isEqualTo(LaunchNoteTaskActivity::class.java.name)
+ assertThat(actualShortcut.intent?.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
+ assertThat(actualShortcut.shortLabel).isEqualTo(NOTES_SHORT_LABEL)
+ assertThat(actualShortcut.isLongLived).isEqualTo(true)
+ assertThat(actualShortcut.icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
+ assertThat(actualShortcut.extras?.getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE))
+ .isEqualTo(NOTES_PACKAGE_NAME)
+ }
+
+ @Test
+ fun updateNoteTaskAsUser_noNotesRole_shouldDisableShortcuts() {
+ whenever(roleManager.getRoleHoldersAsUser(ROLE_NOTES, userTracker.userHandle))
+ .thenReturn(emptyList())
+
+ createNoteTaskController(isEnabled = true).updateNoteTaskAsUser(userTracker.userHandle)
+
+ val argument = argumentCaptor<ComponentName>()
+ verify(context.packageManager)
+ .setComponentEnabledSetting(
+ argument.capture(),
+ eq(COMPONENT_ENABLED_STATE_DISABLED),
+ eq(PackageManager.DONT_KILL_APP),
+ )
+ assertThat(argument.value.className)
+ .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+ verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
+ verify(shortcutManager, never()).enableShortcuts(any())
+ verify(shortcutManager, never()).updateShortcuts(any())
+ }
+
+ @Test
+ fun updateNoteTaskAsUser_flagDisabled_shouldDisableShortcuts() {
+ createNoteTaskController(isEnabled = false).updateNoteTaskAsUser(userTracker.userHandle)
+
+ val argument = argumentCaptor<ComponentName>()
+ verify(context.packageManager)
+ .setComponentEnabledSetting(
+ argument.capture(),
+ eq(COMPONENT_ENABLED_STATE_DISABLED),
+ eq(PackageManager.DONT_KILL_APP),
+ )
+ assertThat(argument.value.className)
+ .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
+ verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
+ verify(shortcutManager, never()).enableShortcuts(any())
+ verify(shortcutManager, never()).updateShortcuts(any())
+ }
+ // endregion
+
private companion object {
+ const val NOTES_SHORT_LABEL = "Notetaking"
const val NOTES_PACKAGE_NAME = "com.android.note.app"
const val NOTES_UID = 123456
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
index 46e0278..cd67e8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
@@ -15,36 +15,37 @@
*/
package com.android.systemui.notetask
+import android.app.role.RoleManager
import android.test.suitebuilder.annotation.SmallTest
import android.view.KeyEvent
import androidx.test.runner.AndroidJUnit4
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
-/**
- * Tests for [NoteTaskController].
- *
- * Build/Install/Run:
- * - atest SystemUITests:NoteTaskInitializerTest
- */
+/** atest SystemUITests:NoteTaskInitializerTest */
@SmallTest
@RunWith(AndroidJUnit4::class)
internal class NoteTaskInitializerTest : SysuiTestCase() {
@Mock lateinit var commandQueue: CommandQueue
@Mock lateinit var bubbles: Bubbles
- @Mock lateinit var noteTaskController: NoteTaskController
+ @Mock lateinit var controller: NoteTaskController
+ @Mock lateinit var roleManager: RoleManager
+ private val clock = FakeSystemClock()
+ private val executor = FakeExecutor(clock)
@Before
fun setUp() {
@@ -56,47 +57,41 @@
bubbles: Bubbles? = this.bubbles,
): NoteTaskInitializer {
return NoteTaskInitializer(
- controller = noteTaskController,
+ controller = controller,
commandQueue = commandQueue,
optionalBubbles = Optional.ofNullable(bubbles),
isEnabled = isEnabled,
+ roleManager = roleManager,
+ backgroundExecutor = executor,
)
}
// region initializer
@Test
- fun initialize_shouldAddCallbacks() {
+ fun initialize() {
createNoteTaskInitializer().initialize()
+ verify(controller).setNoteTaskShortcutEnabled(true)
verify(commandQueue).addCallback(any())
+ verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
}
@Test
- fun initialize_flagDisabled_shouldDoNothing() {
+ fun initialize_flagDisabled() {
createNoteTaskInitializer(isEnabled = false).initialize()
+ verify(controller, never()).setNoteTaskShortcutEnabled(any())
verify(commandQueue, never()).addCallback(any())
+ verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
}
@Test
- fun initialize_bubblesNotPresent_shouldDoNothing() {
+ fun initialize_bubblesNotPresent() {
createNoteTaskInitializer(bubbles = null).initialize()
+ verify(controller, never()).setNoteTaskShortcutEnabled(any())
verify(commandQueue, never()).addCallback(any())
- }
-
- @Test
- fun initialize_flagEnabled_shouldEnableShortcut() {
- createNoteTaskInitializer().initialize()
-
- verify(noteTaskController).setNoteTaskShortcutEnabled(true)
- }
-
- @Test
- fun initialize_flagDisabled_shouldDisableShortcut() {
- createNoteTaskInitializer(isEnabled = false).initialize()
-
- verify(noteTaskController).setNoteTaskShortcutEnabled(false)
+ verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
}
// endregion
@@ -105,14 +100,14 @@
fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL)
- verify(noteTaskController).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
+ verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
}
@Test
fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent.KEYCODE_UNKNOWN)
- verifyZeroInteractions(noteTaskController)
+ verifyZeroInteractions(controller)
}
// endregion
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index 75fd000..2e77de2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -1,6 +1,6 @@
package com.android.systemui.qs.tiles
-import android.content.Context
+import android.bluetooth.BluetoothDevice
import android.os.Handler
import android.os.Looper
import android.os.UserManager
@@ -10,6 +10,8 @@
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.settingslib.Utils
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
@@ -21,14 +23,18 @@
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.statusbar.policy.BluetoothController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.`when`
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -36,21 +42,13 @@
@SmallTest
class BluetoothTileTest : SysuiTestCase() {
- @Mock
- private lateinit var mockContext: Context
- @Mock
- private lateinit var qsLogger: QSLogger
- @Mock
- private lateinit var qsHost: QSHost
- @Mock
- private lateinit var metricsLogger: MetricsLogger
+ @Mock private lateinit var qsLogger: QSLogger
+ @Mock private lateinit var qsHost: QSHost
+ @Mock private lateinit var metricsLogger: MetricsLogger
private val falsingManager = FalsingManagerFake()
- @Mock
- private lateinit var statusBarStateController: StatusBarStateController
- @Mock
- private lateinit var activityStarter: ActivityStarter
- @Mock
- private lateinit var bluetoothController: BluetoothController
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
+ @Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var bluetoothController: BluetoothController
private val uiEventLogger = UiEventLoggerFake()
private lateinit var testableLooper: TestableLooper
@@ -61,20 +59,21 @@
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
- Mockito.`when`(qsHost.context).thenReturn(mockContext)
- Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+ whenever(qsHost.context).thenReturn(mContext)
+ whenever(qsHost.uiEventLogger).thenReturn(uiEventLogger)
- tile = FakeBluetoothTile(
- qsHost,
- testableLooper.looper,
- Handler(testableLooper.looper),
- falsingManager,
- metricsLogger,
- statusBarStateController,
- activityStarter,
- qsLogger,
- bluetoothController
- )
+ tile =
+ FakeBluetoothTile(
+ qsHost,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ falsingManager,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ bluetoothController,
+ )
tile.initialize()
testableLooper.processAllMessages()
@@ -102,7 +101,7 @@
tile.handleUpdateState(state, /* arg= */ null)
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
}
@Test
@@ -114,7 +113,7 @@
tile.handleUpdateState(state, /* arg= */ null)
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
}
@Test
@@ -126,7 +125,7 @@
tile.handleUpdateState(state, /* arg= */ null)
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_on))
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_on))
}
@Test
@@ -138,7 +137,76 @@
tile.handleUpdateState(state, /* arg= */ null)
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_search))
+ .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_search))
+ }
+
+ @Test
+ fun testSecondaryLabel_whenBatteryMetadataAvailable_isMetadataBatteryLevelState() {
+ val cachedDevice = mock<CachedBluetoothDevice>()
+ val state = QSTile.BooleanState()
+ listenToDeviceMetadata(state, cachedDevice, 50)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.secondaryLabel)
+ .isEqualTo(
+ mContext.getString(
+ R.string.quick_settings_bluetooth_secondary_label_battery_level,
+ Utils.formatPercentage(50)
+ )
+ )
+ verify(bluetoothController)
+ .addOnMetadataChangedListener(eq(cachedDevice), any(), any())
+ }
+
+ @Test
+ fun testSecondaryLabel_whenBatteryMetadataUnavailable_isBluetoothBatteryLevelState() {
+ val state = QSTile.BooleanState()
+ val cachedDevice = mock<CachedBluetoothDevice>()
+ listenToDeviceMetadata(state, cachedDevice, 50)
+ val cachedDevice2 = mock<CachedBluetoothDevice>()
+ val btDevice = mock<BluetoothDevice>()
+ whenever(cachedDevice2.device).thenReturn(btDevice)
+ whenever(btDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn(null)
+ whenever(cachedDevice2.batteryLevel).thenReturn(25)
+ addConnectedDevice(cachedDevice2)
+
+ tile.handleUpdateState(state, /* arg= */ null)
+
+ assertThat(state.secondaryLabel)
+ .isEqualTo(
+ mContext.getString(
+ R.string.quick_settings_bluetooth_secondary_label_battery_level,
+ Utils.formatPercentage(25)
+ )
+ )
+ verify(bluetoothController, times(1))
+ .removeOnMetadataChangedListener(eq(cachedDevice), any())
+ }
+
+ @Test
+ fun testMetadataListener_whenDisconnected_isUnregistered() {
+ val state = QSTile.BooleanState()
+ val cachedDevice = mock<CachedBluetoothDevice>()
+ listenToDeviceMetadata(state, cachedDevice, 50)
+ disableBluetooth()
+
+ tile.handleUpdateState(state, null)
+
+ verify(bluetoothController, times(1))
+ .removeOnMetadataChangedListener(eq(cachedDevice), any())
+ }
+
+ @Test
+ fun testMetadataListener_whenTileNotListening_isUnregistered() {
+ val state = QSTile.BooleanState()
+ val cachedDevice = mock<CachedBluetoothDevice>()
+ listenToDeviceMetadata(state, cachedDevice, 50)
+
+ tile.handleSetListening(false)
+
+ verify(bluetoothController, times(1))
+ .removeOnMetadataChangedListener(eq(cachedDevice), any())
}
private class FakeBluetoothTile(
@@ -150,18 +218,19 @@
statusBarStateController: StatusBarStateController,
activityStarter: ActivityStarter,
qsLogger: QSLogger,
- bluetoothController: BluetoothController
- ) : BluetoothTile(
- qsHost,
- backgroundLooper,
- mainHandler,
- falsingManager,
- metricsLogger,
- statusBarStateController,
- activityStarter,
- qsLogger,
- bluetoothController
- ) {
+ bluetoothController: BluetoothController,
+ ) :
+ BluetoothTile(
+ qsHost,
+ backgroundLooper,
+ mainHandler,
+ falsingManager,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ bluetoothController,
+ ) {
var restrictionChecked: String? = null
override fun checkIfRestrictionEnforcedByAdminOnly(
@@ -173,25 +242,44 @@
}
fun enableBluetooth() {
- `when`(bluetoothController.isBluetoothEnabled).thenReturn(true)
+ whenever(bluetoothController.isBluetoothEnabled).thenReturn(true)
}
fun disableBluetooth() {
- `when`(bluetoothController.isBluetoothEnabled).thenReturn(false)
+ whenever(bluetoothController.isBluetoothEnabled).thenReturn(false)
}
fun setBluetoothDisconnected() {
- `when`(bluetoothController.isBluetoothConnecting).thenReturn(false)
- `when`(bluetoothController.isBluetoothConnected).thenReturn(false)
+ whenever(bluetoothController.isBluetoothConnecting).thenReturn(false)
+ whenever(bluetoothController.isBluetoothConnected).thenReturn(false)
}
fun setBluetoothConnected() {
- `when`(bluetoothController.isBluetoothConnecting).thenReturn(false)
- `when`(bluetoothController.isBluetoothConnected).thenReturn(true)
+ whenever(bluetoothController.isBluetoothConnecting).thenReturn(false)
+ whenever(bluetoothController.isBluetoothConnected).thenReturn(true)
}
fun setBluetoothConnecting() {
- `when`(bluetoothController.isBluetoothConnected).thenReturn(false)
- `when`(bluetoothController.isBluetoothConnecting).thenReturn(true)
+ whenever(bluetoothController.isBluetoothConnected).thenReturn(false)
+ whenever(bluetoothController.isBluetoothConnecting).thenReturn(true)
+ }
+
+ fun addConnectedDevice(device: CachedBluetoothDevice) {
+ whenever(bluetoothController.connectedDevices).thenReturn(listOf(device))
+ }
+
+ fun listenToDeviceMetadata(
+ state: QSTile.BooleanState,
+ cachedDevice: CachedBluetoothDevice,
+ batteryLevel: Int
+ ) {
+ val btDevice = mock<BluetoothDevice>()
+ whenever(cachedDevice.device).thenReturn(btDevice)
+ whenever(btDevice.getMetadata(BluetoothDevice.METADATA_MAIN_BATTERY))
+ .thenReturn(batteryLevel.toString().toByteArray())
+ enableBluetooth()
+ setBluetoothConnected()
+ addConnectedDevice(cachedDevice)
+ tile.handleUpdateState(state, /* arg= */ null)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
index 1f18d91..08b5d2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
@@ -19,12 +19,14 @@
import android.content.ComponentName
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.testing.AndroidTestingRunner
import android.view.Display
import android.view.IWindowManager
import android.view.WindowManager
import androidx.test.filters.SmallTest
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argThat
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import junit.framework.Assert.assertEquals
@@ -32,6 +34,7 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatcher
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
@@ -158,4 +161,56 @@
assertEquals(appName2, list[1])
assertEquals(appName3, list[2])
}
+
+ private fun includesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
+ ComponentInfoFlagMatcher(mask, mask)
+ private fun excludesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
+ ComponentInfoFlagMatcher(mask, 0)
+
+ private class ComponentInfoFlagMatcher(
+ @PackageManager.ComponentInfoFlagsBits val mask: Int, val value: Int
+ ): ArgumentMatcher<PackageManager.ComponentInfoFlags> {
+ override fun matches(flags: PackageManager.ComponentInfoFlags): Boolean {
+ return (mask.toLong() and flags.value) == value.toLong()
+ }
+
+ override fun toString(): String{
+ return "mask 0x%08x == 0x%08x".format(mask, value)
+ }
+ }
+
+ @Test
+ fun testMaybeNotifyOfScreenshot_disabledApp() {
+ val data = ScreenshotData.forTesting()
+ data.source = WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD
+
+ val component = ComponentName("package1", "class1")
+ val appName = "app name"
+ val activityInfo = mock(ActivityInfo::class.java)
+
+ whenever(
+ packageManager.getActivityInfo(
+ eq(component),
+ argThat(includesFlagBits(MATCH_DISABLED_COMPONENTS))
+ )
+ ).thenReturn(activityInfo);
+
+ whenever(
+ packageManager.getActivityInfo(
+ eq(component),
+ argThat(excludesFlagBits(MATCH_DISABLED_COMPONENTS))
+ )
+ ).thenThrow(PackageManager.NameNotFoundException::class.java);
+
+ whenever(windowManager.notifyScreenshotListeners(eq(Display.DEFAULT_DISPLAY)))
+ .thenReturn(listOf(component))
+
+ whenever(activityInfo.loadLabel(eq(packageManager))).thenReturn(appName)
+
+ val list = controller.maybeNotifyOfScreenshot(data)
+
+ assertEquals(1, list.size)
+ assertEquals(appName, list[0])
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
index 3440f91..31f7771 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
@@ -45,7 +45,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -58,8 +57,9 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class WorkProfileMessageControllerTest extends SysuiTestCase {
- private static final String DEFAULT_LABEL = "default label";
- private static final String APP_LABEL = "app label";
+ private static final String FILES_APP_COMPONENT = "com.android.test/.FilesComponent";
+ private static final String FILES_APP_LABEL = "Custom Files App";
+ private static final String DEFAULT_FILES_APP_LABEL = "Files";
private static final UserHandle NON_WORK_USER = UserHandle.of(0);
private static final UserHandle WORK_USER = UserHandle.of(10);
@@ -88,14 +88,21 @@
when(mMockContext.getSharedPreferences(
eq(WorkProfileMessageController.SHARED_PREFERENCES_NAME),
eq(Context.MODE_PRIVATE))).thenReturn(mSharedPreferences);
- when(mMockContext.getString(ArgumentMatchers.anyInt())).thenReturn(DEFAULT_LABEL);
- when(mPackageManager.getActivityIcon(any(ComponentName.class)))
+ when(mMockContext.getString(R.string.config_sceenshotWorkProfileFilesApp))
+ .thenReturn(FILES_APP_COMPONENT);
+ when(mMockContext.getString(R.string.screenshot_default_files_app_name))
+ .thenReturn(DEFAULT_FILES_APP_LABEL);
+ when(mPackageManager.getActivityIcon(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT))))
.thenReturn(mActivityIcon);
- when(mPackageManager.getUserBadgedIcon(
- any(), any())).thenReturn(mBadgedActivityIcon);
- when(mPackageManager.getActivityInfo(any(),
- any(PackageManager.ComponentInfoFlags.class))).thenReturn(mActivityInfo);
- when(mActivityInfo.loadLabel(eq(mPackageManager))).thenReturn(APP_LABEL);
+ when(mPackageManager.getUserBadgedIcon(any(), any()))
+ .thenReturn(mBadgedActivityIcon);
+ when(mPackageManager.getActivityInfo(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT)),
+ any(PackageManager.ComponentInfoFlags.class)))
+ .thenReturn(mActivityInfo);
+ when(mActivityInfo.loadLabel(eq(mPackageManager)))
+ .thenReturn(FILES_APP_LABEL);
mSharedPreferences.edit().putBoolean(
WorkProfileMessageController.PREFERENCE_KEY, false).apply();
@@ -120,14 +127,15 @@
@Test
public void testOnScreenshotTaken_packageNotFound()
throws PackageManager.NameNotFoundException {
- when(mPackageManager.getActivityInfo(any(),
+ when(mPackageManager.getActivityInfo(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT)),
any(PackageManager.ComponentInfoFlags.class))).thenThrow(
new PackageManager.NameNotFoundException());
WorkProfileMessageController.WorkProfileFirstRunData data =
mMessageController.onScreenshotTaken(WORK_USER);
- assertEquals(DEFAULT_LABEL, data.getAppName());
+ assertEquals(DEFAULT_FILES_APP_LABEL, data.getAppName());
assertNull(data.getIcon());
}
@@ -136,16 +144,28 @@
WorkProfileMessageController.WorkProfileFirstRunData data =
mMessageController.onScreenshotTaken(WORK_USER);
- assertEquals(APP_LABEL, data.getAppName());
+ assertEquals(FILES_APP_LABEL, data.getAppName());
assertEquals(mBadgedActivityIcon, data.getIcon());
}
@Test
+ public void testOnScreenshotTaken_noFilesAppComponentDefined() {
+ when(mMockContext.getString(R.string.config_sceenshotWorkProfileFilesApp))
+ .thenReturn("");
+
+ WorkProfileMessageController.WorkProfileFirstRunData data =
+ mMessageController.onScreenshotTaken(WORK_USER);
+
+ assertEquals(DEFAULT_FILES_APP_LABEL, data.getAppName());
+ assertNull(data.getIcon());
+ }
+
+ @Test
public void testPopulateView() throws InterruptedException {
ViewGroup layout = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.screenshot_work_profile_first_run, null);
WorkProfileMessageController.WorkProfileFirstRunData data =
- new WorkProfileMessageController.WorkProfileFirstRunData(APP_LABEL,
+ new WorkProfileMessageController.WorkProfileFirstRunData(FILES_APP_LABEL,
mBadgedActivityIcon);
final CountDownLatch countdown = new CountDownLatch(1);
mMessageController.populateView(layout, data, () -> {
@@ -157,7 +177,7 @@
assertEquals(mBadgedActivityIcon, image.getDrawable());
TextView text = layout.findViewById(R.id.screenshot_message_content);
// The app name is used in a template, but at least validate that it was inserted.
- assertTrue(text.getText().toString().contains(APP_LABEL));
+ assertTrue(text.getText().toString().contains(FILES_APP_LABEL));
// Validate that clicking the dismiss button calls back properly.
assertEquals(1, countdown.getCount());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 99cf8d0..7087c01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -24,7 +24,9 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
@@ -184,6 +186,7 @@
@Mock protected NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock protected KeyguardBottomAreaView mKeyguardBottomArea;
@Mock protected KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
+ @Mock protected ViewPropertyAnimator mViewPropertyAnimator;
@Mock protected KeyguardBottomAreaView mQsFrame;
@Mock protected HeadsUpManagerPhone mHeadsUpManager;
@Mock protected NotificationShelfController mNotificationShelfController;
@@ -357,7 +360,14 @@
.thenReturn(mHeadsUpCallback);
when(mKeyguardBottomAreaViewController.getView()).thenReturn(mKeyguardBottomArea);
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
- when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
+ when(mKeyguardBottomArea.animate()).thenReturn(mViewPropertyAnimator);
+ when(mView.animate()).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.translationX(anyFloat())).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.setInterpolator(any())).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.setListener(any())).thenReturn(mViewPropertyAnimator);
+ when(mViewPropertyAnimator.setUpdateListener(any())).thenReturn(mViewPropertyAnimator);
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 9a2e415..d36cc7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -42,6 +42,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.animation.Animator;
+import android.animation.ValueAnimator;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
@@ -693,6 +695,24 @@
}
@Test
+ public void testFoldToAodAnimationCleansupInAnimationEnd() {
+ ArgumentCaptor<Animator.AnimatorListener> animCaptor =
+ ArgumentCaptor.forClass(Animator.AnimatorListener.class);
+ ArgumentCaptor<ValueAnimator.AnimatorUpdateListener> updateCaptor =
+ ArgumentCaptor.forClass(ValueAnimator.AnimatorUpdateListener.class);
+
+ // Start fold animation & Capture Listeners
+ mNotificationPanelViewController.startFoldToAodAnimation(() -> {}, () -> {}, () -> {});
+ verify(mViewPropertyAnimator).setListener(animCaptor.capture());
+ verify(mViewPropertyAnimator).setUpdateListener(updateCaptor.capture());
+
+ // End animation and validate listeners were unset
+ animCaptor.getValue().onAnimationEnd(null);
+ verify(mViewPropertyAnimator).setListener(null);
+ verify(mViewPropertyAnimator).setUpdateListener(null);
+ }
+
+ @Test
public void testExpandWithQsMethodIsUsingLockscreenTransitionController() {
enableSplitShade(/* enabled= */ true);
mStatusBarStateController.setState(KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index dd79297..526dc8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -223,16 +223,6 @@
}
@Test
- public void attach_fadingAway_wallpaperVisible() {
- clearInvocations(mWindowManager);
- mNotificationShadeWindowController.attach();
- mNotificationShadeWindowController.setKeyguardFadingAway(true);
-
- verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
- assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue();
- }
-
- @Test
public void setBackgroundBlurRadius_expandedWithBlurs() {
mNotificationShadeWindowController.setBackgroundBlurRadius(10);
verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 251aced..569f90b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -105,6 +105,7 @@
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -188,6 +189,8 @@
private AuthController mAuthController;
@Mock
private AlarmManager mAlarmManager;
+ @Mock
+ private UserTracker mUserTracker;
@Captor
private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@Captor
@@ -209,6 +212,7 @@
private BroadcastReceiver mBroadcastReceiver;
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private TestableLooper mTestableLooper;
+ private final int mCurrentUserId = 1;
private KeyguardIndicationTextView mTextView; // AOD text
@@ -260,6 +264,7 @@
.thenReturn(mDisclosureGeneric);
when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
.thenReturn(mDisclosureWithOrganization);
+ when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
mWakeLock = new WakeLockFake();
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
@@ -291,7 +296,8 @@
mKeyguardBypassController, mAccessibilityManager,
mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
mAlternateBouncerInteractor,
- mAlarmManager
+ mAlarmManager,
+ mUserTracker
);
mController.init();
mController.setIndicationArea(mIndicationArea);
@@ -813,7 +819,7 @@
public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() {
createController();
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
String message = "A message";
mController.setVisible(true);
@@ -828,7 +834,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help messages received that are allowed to show
final String helpString = "helpString";
@@ -855,7 +861,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help messages received that aren't supposed to show
final String helpString = "helpString";
@@ -882,7 +888,7 @@
// GIVEN fingerprint NOT enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(false);
+ getCurrentUser())).thenReturn(false);
// WHEN help messages received
final Set<CharSequence> helpStrings = new HashSet<>();
@@ -913,7 +919,7 @@
// GIVEN fingerprint NOT enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(false);
+ getCurrentUser())).thenReturn(false);
// WHEN help message received and deferred message is valid
final String helpString = "helpMsg";
@@ -944,7 +950,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help message received and deferredMessage is valid
final String helpString = "helpMsg";
@@ -1173,7 +1179,7 @@
// WHEN trust is granted
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
- mKeyguardUpdateMonitorCallback.onTrustChanged(KeyguardUpdateMonitor.getCurrentUser());
+ mKeyguardUpdateMonitorCallback.onTrustChanged(getCurrentUser());
// THEN verify the trust granted message shows
verifyIndicationMessage(
@@ -1238,7 +1244,7 @@
public void coEx_faceSuccess_showsPressToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(false);
@@ -1262,7 +1268,7 @@
public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1286,7 +1292,7 @@
public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1309,7 +1315,7 @@
public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, no udfps supported
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
@@ -1331,7 +1337,7 @@
public void udfpsOnly_a11yEnabled_showsSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1351,7 +1357,7 @@
public void udfpsOnly_showsPressToOpen() {
// GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(false);
@@ -1372,7 +1378,7 @@
// GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported,
// face wasn't authenticated)
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
@@ -1390,7 +1396,7 @@
public void cannotSkipBouncer_showSwipeToUnlockHint() {
// GIVEN bouncer isn't showing and cannot skip bouncer
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(false);
createController();
mController.setVisible(true);
@@ -1746,10 +1752,14 @@
private void setupFingerprintUnlockPossible(boolean possible) {
when(mKeyguardUpdateMonitor
- .getCachedIsUnlockWithFingerprintPossible(KeyguardUpdateMonitor.getCurrentUser()))
+ .getCachedIsUnlockWithFingerprintPossible(getCurrentUser()))
.thenReturn(possible);
}
+ private int getCurrentUser() {
+ return mCurrentUserId;
+ }
+
private void onFaceLockoutError(String errMsg) {
mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_LOCKOUT_PERMANENT,
errMsg,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index b6b0b77..9b6d293 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -41,6 +41,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
@@ -103,6 +104,7 @@
@Mock private SecureSettings mSecureSettings;
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
+ @Mock private UserTracker mUserTracker;
private NotifUiAdjustmentProvider mAdjustmentProvider;
@@ -118,7 +120,8 @@
mHandler,
mSecureSettings,
mLockscreenUserManager,
- mSectionStyleProvider);
+ mSectionStyleProvider,
+ mUserTracker);
mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build();
mInflationError = new Exception(TEST_MESSAGE);
mErrorManager = new NotifInflationErrorManager();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
index 246943e..f9f8d8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
@@ -22,6 +22,7 @@
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
@@ -53,6 +54,7 @@
private val secureSettings: SecureSettings = mock()
private val uri = FakeSettings().getUriFor(SHOW_NOTIFICATION_SNOOZE)
private val dirtyListener: Runnable = mock()
+ private val userTracker: UserTracker = mock()
private val section = NotifSection(mock(), 0)
private val entry = NotificationEntryBuilder()
@@ -67,13 +69,14 @@
secureSettings,
lockscreenUserManager,
sectionStyleProvider,
+ userTracker
)
@Before
fun setup() {
verifyNoMoreInteractions(secureSettings)
adjustmentProvider.addDirtyListener(dirtyListener)
- verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())
+ verify(secureSettings).getIntForUser(eq(SHOW_NOTIFICATION_SNOOZE), any(), any())
contentObserver = withArgCaptor {
verify(secureSettings).registerContentObserverForUser(
eq(SHOW_NOTIFICATION_SNOOZE), capture(), any()
@@ -105,18 +108,20 @@
fun onChangeWillQueryThenNotifyDirty() {
contentObserver.onChange(false, listOf(uri), 0, 0)
with(inOrder(secureSettings, dirtyListener)) {
- verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())
+ verify(secureSettings).getIntForUser(eq(SHOW_NOTIFICATION_SNOOZE), any(), any())
verify(dirtyListener).run()
}
}
@Test
fun changingSnoozeChangesProvidedAdjustment() {
- whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(0)
+ whenever(secureSettings.getIntForUser(eq(SHOW_NOTIFICATION_SNOOZE), any(), any()))
+ .thenReturn(0)
val original = adjustmentProvider.calculateAdjustment(entry)
assertThat(original.isSnoozeEnabled).isFalse()
- whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(1)
+ whenever(secureSettings.getIntForUser(eq(SHOW_NOTIFICATION_SNOOZE), any(), any()))
+ .thenReturn(1)
contentObserver.onChange(false, listOf(uri), 0, 0)
val withSnoozing = adjustmentProvider.calculateAdjustment(entry)
assertThat(withSnoozing.isSnoozeEnabled).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index e3516f97..e929028 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -15,7 +15,6 @@
package com.android.systemui.statusbar.notification.row;
import static android.provider.Settings.Global.SHOW_NEW_NOTIF_DISMISS;
-import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static junit.framework.Assert.assertEquals;
@@ -100,7 +99,7 @@
@Test
public void testNoAppOpsInSlowSwipe() {
- Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, 0);
+ when(mRow.getShowSnooze()).thenReturn(false);
Settings.Global.putInt(mContext.getContentResolver(), SHOW_NEW_NOTIF_DISMISS, 0);
NotificationMenuRow row = new NotificationMenuRow(mContext, mPeopleNotificationIdentifier);
@@ -113,7 +112,7 @@
@Test
public void testNoSnoozeInSlowSwipe() {
- Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, 0);
+ when(mRow.getShowSnooze()).thenReturn(false);
Settings.Global.putInt(mContext.getContentResolver(), SHOW_NEW_NOTIF_DISMISS, 0);
NotificationMenuRow row = new NotificationMenuRow(mContext, mPeopleNotificationIdentifier);
@@ -126,7 +125,7 @@
@Test
public void testSnoozeInSlowSwipe() {
- Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, 1);
+ when(mRow.getShowSnooze()).thenReturn(true);
Settings.Global.putInt(mContext.getContentResolver(), SHOW_NEW_NOTIF_DISMISS, 0);
NotificationMenuRow row = new NotificationMenuRow(mContext, mPeopleNotificationIdentifier);
@@ -139,7 +138,7 @@
@Test
public void testSlowSwipe_newDismiss() {
- Settings.Secure.putInt(mContext.getContentResolver(), SHOW_NOTIFICATION_SNOOZE, 1);
+ when(mRow.getShowSnooze()).thenReturn(true);
Settings.Global.putInt(mContext.getContentResolver(), SHOW_NEW_NOTIF_DISMISS, 1);
NotificationMenuRow row = new NotificationMenuRow(mContext, mPeopleNotificationIdentifier);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 78da782..824eb4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -425,12 +425,12 @@
public void testGetViewTranslationAnimator_notExpandableNotificationRow() {
Animator animator = mock(Animator.class);
AnimatorUpdateListener listener = mock(AnimatorUpdateListener.class);
- doReturn(animator).when(mSwipeHelper).superGetViewTranslationAnimator(mView, 0, listener);
+ doReturn(animator).when(mSwipeHelper).createTranslationAnimation(mView, 0, listener);
- assertEquals("returns the correct animator from super", animator,
+ assertEquals("Should create a new animator", animator,
mSwipeHelper.getViewTranslationAnimator(mView, 0, listener));
- verify(mSwipeHelper, times(1)).superGetViewTranslationAnimator(mView, 0, listener);
+ verify(mSwipeHelper).createTranslationAnimation(mView, 0, listener);
}
@Test
@@ -439,10 +439,10 @@
AnimatorUpdateListener listener = mock(AnimatorUpdateListener.class);
doReturn(animator).when(mNotificationRow).getTranslateViewAnimator(0, listener);
- assertEquals("returns the correct animator from super when view is an ENR", animator,
+ assertEquals("Should return the animator from ExpandableNotificationRow", animator,
mSwipeHelper.getViewTranslationAnimator(mNotificationRow, 0, listener));
- verify(mNotificationRow, times(1)).getTranslateViewAnimator(0, listener);
+ verify(mNotificationRow).getTranslateViewAnimator(0, listener);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 1aba1fc..7db2197 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -1342,18 +1342,6 @@
}
@Test
- public void keyguard_notHidden_ifGoingAwayAndOccluded() {
- setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
-
- when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
- when(mKeyguardStateController.isOccluded()).thenReturn(true);
-
- mCentralSurfaces.updateIsKeyguard(false);
-
- verify(mStatusBarStateController, never()).setState(eq(SHADE), anyBoolean());
- }
-
- @Test
public void frpLockedDevice_shadeDisabled() {
when(mDeviceProvisionedController.isFrpActive()).thenReturn(true);
when(mDozeServiceHost.isPulsing()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 542b688..934e1c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -25,7 +25,6 @@
import android.telephony.TelephonyCallback
import android.telephony.TelephonyCallback.DataActivityListener
import android.telephony.TelephonyCallback.ServiceStateListener
-import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
import android.telephony.TelephonyManager
@@ -68,6 +67,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.telephonyDisplayInfo
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
@@ -392,13 +392,17 @@
val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
- val type = NETWORK_TYPE_UNKNOWN
- val expected = UnknownNetworkType
- val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
+ val ti =
+ telephonyDisplayInfo(
+ networkType = NETWORK_TYPE_UNKNOWN,
+ overrideNetworkType = NETWORK_TYPE_UNKNOWN,
+ )
+
callback.onDisplayInfoChanged(ti)
+ val expected = UnknownNetworkType
assertThat(latest).isEqualTo(expected)
- assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(type))
+ assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(NETWORK_TYPE_UNKNOWN))
job.cancel()
}
@@ -412,14 +416,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val overrideType = OVERRIDE_NETWORK_TYPE_NONE
val type = NETWORK_TYPE_LTE
- val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.overrideNetworkType).thenReturn(overrideType)
- whenever(it.networkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = overrideType)
callback.onDisplayInfoChanged(ti)
+ val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
@@ -433,14 +433,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
- val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.networkType).thenReturn(type)
- whenever(it.overrideNetworkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = type)
callback.onDisplayInfoChanged(ti)
+ val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
@@ -455,14 +451,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val unknown = NETWORK_TYPE_UNKNOWN
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
- val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.networkType).thenReturn(unknown)
- whenever(it.overrideNetworkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(unknown, type)
callback.onDisplayInfoChanged(ti)
+ val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
index bbf04ed2..9da9ff7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
@@ -64,10 +64,14 @@
*
* Kind of like an interaction test case build just for [TelephonyCallback]
*
- * The list of telephony callbacks we use is: [TelephonyCallback.CarrierNetworkListener]
- * [TelephonyCallback.DataActivityListener] [TelephonyCallback.DataConnectionStateListener]
- * [TelephonyCallback.DataEnabledListener] [TelephonyCallback.DisplayInfoListener]
- * [TelephonyCallback.ServiceStateListener] [TelephonyCallback.SignalStrengthsListener]
+ * The list of telephony callbacks we use is:
+ * - [TelephonyCallback.CarrierNetworkListener]
+ * - [TelephonyCallback.DataActivityListener]
+ * - [TelephonyCallback.DataConnectionStateListener]
+ * - [TelephonyCallback.DataEnabledListener]
+ * - [TelephonyCallback.DisplayInfoListener]
+ * - [TelephonyCallback.ServiceStateListener]
+ * - [TelephonyCallback.SignalStrengthsListener]
*
* Because each of these callbacks comes in on the same callbackFlow, collecting on a field backed
* by only a single callback can immediately create backpressure on the other fields related to a
@@ -201,7 +205,6 @@
200 /* unused */
)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val connectionJob = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
@@ -225,7 +228,6 @@
enabledCallback.onDataEnabledChanged(true, 1 /* unused */)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
@@ -252,7 +254,6 @@
val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
displayInfoCallback.onDisplayInfoChanged(ti)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
index d07b96f..cf815c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
@@ -19,6 +19,7 @@
import android.telephony.CellSignalStrengthCdma
import android.telephony.SignalStrength
import android.telephony.TelephonyCallback
+import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
@@ -48,6 +49,12 @@
return signalStrength
}
+ fun telephonyDisplayInfo(networkType: Int, overrideNetworkType: Int) =
+ mock<TelephonyDisplayInfo>().also {
+ whenever(it.networkType).thenReturn(networkType)
+ whenever(it.overrideNetworkType).thenReturn(overrideNetworkType)
+ }
+
inline fun <reified T> getTelephonyCallbackForType(mockTelephonyManager: TelephonyManager): T {
val cbs = getTelephonyCallbacks(mockTelephonyManager).filterIsInstance<T>()
assertThat(cbs.size).isEqualTo(1)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index 64810d2..5c19108 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -30,6 +30,7 @@
import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
+import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
@@ -43,6 +44,7 @@
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel.Companion.viewModelForLocation
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
@@ -93,18 +95,23 @@
tableLogBuffer,
scope,
)
- viewModel =
+ val viewModelCommon =
WifiViewModel(
- airplaneModeViewModel,
- connectivityConstants,
- context,
- tableLogBuffer,
- interactor,
- scope,
- statusBarPipelineFlags,
- wifiConstants,
- )
- .home
+ airplaneModeViewModel,
+ connectivityConstants,
+ context,
+ tableLogBuffer,
+ interactor,
+ scope,
+ statusBarPipelineFlags,
+ wifiConstants,
+ )
+ viewModel =
+ viewModelForLocation(
+ viewModelCommon,
+ statusBarPipelineFlags,
+ StatusBarLocation.HOME,
+ )
}
// Note: The following tests are more like integration tests, since they stand up a full
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
index 1c71f8b..ffe990b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
@@ -130,7 +130,7 @@
wifiConstants,
)
- val iconFlow = underTest.home.wifiIcon
+ val iconFlow = underTest.wifiIcon
val job = iconFlow.launchIn(this)
// WHEN we set a certain network
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 7a62cb8..802e360 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -19,6 +19,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
@@ -34,6 +35,7 @@
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
+import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel.Companion.viewModelForLocation
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -105,15 +107,20 @@
@Test
fun wifiIcon_allLocationViewModelsReceiveSameData() =
runBlocking(IMMEDIATE) {
+ val home =
+ viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.HOME)
+ val keyguard =
+ viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.KEYGUARD)
+ val qs = viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.QS)
+
var latestHome: WifiIcon? = null
- val jobHome = underTest.home.wifiIcon.onEach { latestHome = it }.launchIn(this)
+ val jobHome = home.wifiIcon.onEach { latestHome = it }.launchIn(this)
var latestKeyguard: WifiIcon? = null
- val jobKeyguard =
- underTest.keyguard.wifiIcon.onEach { latestKeyguard = it }.launchIn(this)
+ val jobKeyguard = keyguard.wifiIcon.onEach { latestKeyguard = it }.launchIn(this)
var latestQs: WifiIcon? = null
- val jobQs = underTest.qs.wifiIcon.onEach { latestQs = it }.launchIn(this)
+ val jobQs = qs.wifiIcon.onEach { latestQs = it }.launchIn(this)
wifiRepository.setWifiNetwork(
WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 1)
@@ -138,15 +145,15 @@
var activityIn: Boolean? = null
val activityInJob =
- underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
+ underTest.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
var activityOut: Boolean? = null
val activityOutJob =
- underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
+ underTest.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
var activityContainer: Boolean? = null
val activityContainerJob =
- underTest.home.isActivityContainerVisible
+ underTest.isActivityContainerVisible
.onEach { activityContainer = it }
.launchIn(this)
@@ -169,15 +176,15 @@
var activityIn: Boolean? = null
val activityInJob =
- underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
+ underTest.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
var activityOut: Boolean? = null
val activityOutJob =
- underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
+ underTest.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
var activityContainer: Boolean? = null
val activityContainerJob =
- underTest.home.isActivityContainerVisible
+ underTest.isActivityContainerVisible
.onEach { activityContainer = it }
.launchIn(this)
@@ -208,15 +215,15 @@
var activityIn: Boolean? = null
val activityInJob =
- underTest.home.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
+ underTest.isActivityInViewVisible.onEach { activityIn = it }.launchIn(this)
var activityOut: Boolean? = null
val activityOutJob =
- underTest.home.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
+ underTest.isActivityOutViewVisible.onEach { activityOut = it }.launchIn(this)
var activityContainer: Boolean? = null
val activityContainerJob =
- underTest.home.isActivityContainerVisible
+ underTest.isActivityContainerVisible
.onEach { activityContainer = it }
.launchIn(this)
@@ -242,18 +249,21 @@
createAndSetViewModel()
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
+ val home =
+ viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.HOME)
+ val keyguard =
+ viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.KEYGUARD)
+ val qs = viewModelForLocation(underTest, statusBarPipelineFlags, StatusBarLocation.QS)
+
var latestHome: Boolean? = null
- val jobHome =
- underTest.home.isActivityInViewVisible.onEach { latestHome = it }.launchIn(this)
+ val jobHome = home.isActivityInViewVisible.onEach { latestHome = it }.launchIn(this)
var latestKeyguard: Boolean? = null
val jobKeyguard =
- underTest.keyguard.isActivityInViewVisible
- .onEach { latestKeyguard = it }
- .launchIn(this)
+ keyguard.isActivityInViewVisible.onEach { latestKeyguard = it }.launchIn(this)
var latestQs: Boolean? = null
- val jobQs = underTest.qs.isActivityInViewVisible.onEach { latestQs = it }.launchIn(this)
+ val jobQs = qs.isActivityInViewVisible.onEach { latestQs = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
@@ -276,7 +286,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job = underTest.home.isActivityInViewVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityInViewVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
@@ -295,7 +305,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job = underTest.home.isActivityInViewVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityInViewVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
@@ -314,7 +324,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job = underTest.home.isActivityOutViewVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityOutViewVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
@@ -333,7 +343,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job = underTest.home.isActivityOutViewVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityOutViewVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
@@ -352,8 +362,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job =
- underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
@@ -372,8 +381,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job =
- underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
@@ -392,8 +400,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job =
- underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = true, hasActivityOut = true)
wifiRepository.setWifiActivity(activity)
@@ -412,8 +419,7 @@
wifiRepository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
var latest: Boolean? = null
- val job =
- underTest.home.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isActivityContainerVisible.onEach { latest = it }.launchIn(this)
val activity = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
wifiRepository.setWifiActivity(activity)
@@ -428,7 +434,7 @@
fun airplaneSpacer_notAirplaneMode_outputsFalse() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
- val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
airplaneModeRepository.setIsAirplaneMode(false)
yield()
@@ -442,7 +448,7 @@
fun airplaneSpacer_airplaneForceHidden_outputsFalse() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
- val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
airplaneModeRepository.setIsAirplaneMode(true)
connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.AIRPLANE))
@@ -457,7 +463,7 @@
fun airplaneSpacer_airplaneIconVisible_outputsTrue() =
runBlocking(IMMEDIATE) {
var latest: Boolean? = null
- val job = underTest.qs.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
+ val job = underTest.isAirplaneSpacerVisible.onEach { latest = it }.launchIn(this)
airplaneModeRepository.setIsAirplaneMode(true)
yield()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 833cabb..7d64eaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -44,6 +45,8 @@
import com.android.systemui.bluetooth.BluetoothLogger;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -51,6 +54,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -60,10 +64,11 @@
private UserTracker mUserTracker;
private LocalBluetoothManager mMockBluetoothManager;
private CachedBluetoothDeviceManager mMockDeviceManager;
- private LocalBluetoothAdapter mMockAdapter;
+ private LocalBluetoothAdapter mMockLocalAdapter;
private TestableLooper mTestableLooper;
private DumpManager mMockDumpManager;
private BluetoothControllerImpl mBluetoothControllerImpl;
+ private BluetoothAdapter mMockAdapter;
private List<CachedBluetoothDevice> mDevices;
@@ -74,10 +79,11 @@
mDevices = new ArrayList<>();
mUserTracker = mock(UserTracker.class);
mMockDeviceManager = mock(CachedBluetoothDeviceManager.class);
+ mMockAdapter = mock(BluetoothAdapter.class);
when(mMockDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
when(mMockBluetoothManager.getCachedDeviceManager()).thenReturn(mMockDeviceManager);
- mMockAdapter = mock(LocalBluetoothAdapter.class);
- when(mMockBluetoothManager.getBluetoothAdapter()).thenReturn(mMockAdapter);
+ mMockLocalAdapter = mock(LocalBluetoothAdapter.class);
+ when(mMockBluetoothManager.getBluetoothAdapter()).thenReturn(mMockLocalAdapter);
when(mMockBluetoothManager.getEventManager()).thenReturn(mock(BluetoothEventManager.class));
when(mMockBluetoothManager.getProfileManager())
.thenReturn(mock(LocalBluetoothProfileManager.class));
@@ -89,7 +95,8 @@
mock(BluetoothLogger.class),
mTestableLooper.getLooper(),
mTestableLooper.getLooper(),
- mMockBluetoothManager);
+ mMockBluetoothManager,
+ mMockAdapter);
}
@Test
@@ -98,7 +105,8 @@
when(device.isConnected()).thenReturn(true);
when(device.getMaxConnectionState()).thenReturn(BluetoothProfile.STATE_CONNECTED);
mDevices.add(device);
- when(mMockAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_DISCONNECTED);
+ when(mMockLocalAdapter.getConnectionState())
+ .thenReturn(BluetoothAdapter.STATE_DISCONNECTED);
mBluetoothControllerImpl.onConnectionStateChanged(null,
BluetoothAdapter.STATE_DISCONNECTED);
@@ -163,7 +171,7 @@
@Test
public void testOnServiceConnected_updatesConnectionState() {
- when(mMockAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTING);
+ when(mMockLocalAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTING);
mBluetoothControllerImpl.onServiceConnected();
@@ -184,7 +192,7 @@
@Test
public void testOnBluetoothStateChange_updatesConnectionState() {
- when(mMockAdapter.getConnectionState()).thenReturn(
+ when(mMockLocalAdapter.getConnectionState()).thenReturn(
BluetoothAdapter.STATE_CONNECTING,
BluetoothAdapter.STATE_DISCONNECTED);
@@ -240,6 +248,33 @@
assertTrue(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
}
+ @Test
+ public void testAddOnMetadataChangedListener_registersListenerOnAdapter() {
+ CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+ BluetoothDevice device = mock(BluetoothDevice.class);
+ when(cachedDevice.getDevice()).thenReturn(device);
+ Executor executor = new FakeExecutor(new FakeSystemClock());
+ BluetoothAdapter.OnMetadataChangedListener listener = (bluetoothDevice, i, bytes) -> {
+ };
+
+ mBluetoothControllerImpl.addOnMetadataChangedListener(cachedDevice, executor, listener);
+
+ verify(mMockAdapter, times(1)).addOnMetadataChangedListener(device, executor, listener);
+ }
+
+ @Test
+ public void testRemoveOnMetadataChangedListener_removesListenerFromAdapter() {
+ CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+ BluetoothDevice device = mock(BluetoothDevice.class);
+ when(cachedDevice.getDevice()).thenReturn(device);
+ BluetoothAdapter.OnMetadataChangedListener listener = (bluetoothDevice, i, bytes) -> {
+ };
+
+ mBluetoothControllerImpl.removeOnMetadataChangedListener(cachedDevice, listener);
+
+ verify(mMockAdapter, times(1)).removeOnMetadataChangedListener(device, listener);
+ }
+
/** Regression test for b/246876230. */
@Test
public void testOnActiveDeviceChanged_null_noCrash() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
index a707222..66709971 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
@@ -28,6 +28,7 @@
import android.testing.AndroidTestingRunner;
import android.view.AttachedSurfaceControl;
import android.view.View;
+import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
@@ -49,6 +50,9 @@
@Mock
private AttachedSurfaceControl mAttachedSurfaceControl;
+ @Mock
+ private ViewGroup mRootView;
+
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@Before
@@ -228,10 +232,11 @@
private View createView(Rect bounds) {
final Rect rect = new Rect(bounds);
final View view = Mockito.mock(View.class);
+ when(view.getRootView()).thenReturn(mRootView);
doAnswer(invocation -> {
((Rect) invocation.getArgument(0)).set(rect);
return null;
- }).when(view).getBoundsOnScreen(any());
+ }).when(view).getDrawingRect(any());
when(view.isAttachedToWindow()).thenReturn(true);
when(view.getRootSurfaceControl()).thenReturn(mAttachedSurfaceControl);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 8476d0d..bf54d42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -16,6 +16,9 @@
package com.android.systemui.unfold.updates
+import android.content.Context
+import android.content.res.Configuration
+import android.content.res.Resources
import android.os.Handler
import android.testing.AndroidTestingRunner
import androidx.core.util.Consumer
@@ -33,6 +36,7 @@
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import org.junit.Before
@@ -49,20 +53,19 @@
@SmallTest
class DeviceFoldStateProviderTest : SysuiTestCase() {
- @Mock
- private lateinit var activityTypeProvider: ActivityManagerActivityTypeProvider
+ @Mock private lateinit var activityTypeProvider: ActivityManagerActivityTypeProvider
- @Mock
- private lateinit var handler: Handler
+ @Mock private lateinit var handler: Handler
- @Mock
- private lateinit var rotationChangeProvider: RotationChangeProvider
+ @Mock private lateinit var rotationChangeProvider: RotationChangeProvider
- @Mock
- private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider
+ @Mock private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider
- @Captor
- private lateinit var rotationListener: ArgumentCaptor<RotationListener>
+ @Mock private lateinit var resources: Resources
+
+ @Mock private lateinit var context: Context
+
+ @Captor private lateinit var rotationListener: ArgumentCaptor<RotationListener>
private val foldProvider = TestFoldProvider()
private val screenOnStatusProvider = TestScreenOnStatusProvider()
@@ -81,10 +84,13 @@
fun setUp() {
MockitoAnnotations.initMocks(this)
- val config = object : UnfoldTransitionConfig by ResourceUnfoldTransitionConfig() {
- override val halfFoldedTimeoutMillis: Int
- get() = HALF_OPENED_TIMEOUT_MILLIS.toInt()
- }
+ val config =
+ object : UnfoldTransitionConfig by ResourceUnfoldTransitionConfig() {
+ override val halfFoldedTimeoutMillis: Int
+ get() = HALF_OPENED_TIMEOUT_MILLIS.toInt()
+ }
+ whenever(context.resources).thenReturn(resources)
+ whenever(context.mainExecutor).thenReturn(mContext.mainExecutor)
foldStateProvider =
DeviceFoldStateProvider(
@@ -95,6 +101,7 @@
activityTypeProvider,
unfoldKeyguardVisibilityProvider,
rotationChangeProvider,
+ context,
context.mainExecutor,
handler
)
@@ -112,7 +119,8 @@
override fun onUnfoldedScreenAvailable() {
unfoldedScreenAvailabilityUpdates.add(Unit)
}
- })
+ }
+ )
foldStateProvider.start()
verify(rotationChangeProvider).addCallback(capture(rotationListener))
@@ -134,6 +142,7 @@
// By default, we're on launcher.
setupForegroundActivityType(isHomeActivity = true)
+ setIsLargeScreen(true)
}
@Test
@@ -181,7 +190,7 @@
sendHingeAngleEvent(10)
assertThat(foldUpdates)
- .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
+ .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
assertThat(unfoldedScreenAvailabilityUpdates).hasSize(1)
}
@@ -386,8 +395,10 @@
setInitialHingeAngle(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
sendHingeAngleEvent(
- START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
- HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() - 1)
+ START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
+ HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() -
+ 1
+ )
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@@ -429,8 +440,10 @@
setInitialHingeAngle(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
sendHingeAngleEvent(
- START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
- HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() - 1)
+ START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
+ HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() -
+ 1
+ )
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@@ -470,7 +483,7 @@
sendHingeAngleEvent(130)
sendHingeAngleEvent(120)
assertThat(foldUpdates)
- .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
+ .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
}
@Test
@@ -531,8 +544,8 @@
rotationListener.value.onRotationChanged(1)
- assertThat(foldUpdates).containsExactly(
- FOLD_UPDATE_START_OPENING, FOLD_UPDATE_FINISH_HALF_OPEN)
+ assertThat(foldUpdates)
+ .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_FINISH_HALF_OPEN)
}
@Test
@@ -545,6 +558,45 @@
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_FINISH_CLOSED)
}
+ @Test
+ fun onFolding_onSmallScreen_tansitionDoesNotStart() {
+ setIsLargeScreen(false)
+
+ setInitialHingeAngle(120)
+ sendHingeAngleEvent(110)
+ sendHingeAngleEvent(100)
+
+ assertThat(foldUpdates).isEmpty()
+ }
+
+ @Test
+ fun onFolding_onLargeScreen_tansitionStarts() {
+ setIsLargeScreen(true)
+
+ setInitialHingeAngle(120)
+ sendHingeAngleEvent(110)
+ sendHingeAngleEvent(100)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun onUnfold_onSmallScreen_emitsStartOpening() {
+ // the new display state might arrive later, so it shouldn't be used to decide to send the
+ // start opening event, but only for the closing.
+ setFoldState(folded = true)
+ setIsLargeScreen(false)
+ foldUpdates.clear()
+
+ setFoldState(folded = false)
+ screenOnStatusProvider.notifyScreenTurningOn()
+ sendHingeAngleEvent(10)
+ sendHingeAngleEvent(20)
+ screenOnStatusProvider.notifyScreenTurnedOn()
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_OPENING)
+ }
+
private fun setupForegroundActivityType(isHomeActivity: Boolean?) {
whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
}
@@ -566,6 +618,13 @@
foldProvider.notifyFolded(folded)
}
+ private fun setIsLargeScreen(isLargeScreen: Boolean) {
+ val smallestScreenWidth = if (isLargeScreen) { 601 } else { 10 }
+ val configuration = Configuration()
+ configuration.smallestScreenWidthDp = smallestScreenWidth
+ whenever(resources.configuration).thenReturn(configuration)
+ }
+
private fun fireScreenOnEvent() {
screenOnStatusProvider.notifyScreenTurnedOn()
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java
index 6cbd175..4025ade 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeBluetoothController.java
@@ -14,6 +14,7 @@
package com.android.systemui.utils.leaks;
+import android.bluetooth.BluetoothAdapter;
import android.testing.LeakCheck;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -23,6 +24,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Executor;
public class FakeBluetoothController extends BaseLeakChecker<Callback> implements
BluetoothController {
@@ -110,4 +112,16 @@
public List<CachedBluetoothDevice> getConnectedDevices() {
return Collections.emptyList();
}
+
+ @Override
+ public void addOnMetadataChangedListener(CachedBluetoothDevice device, Executor executor,
+ BluetoothAdapter.OnMetadataChangedListener listener) {
+
+ }
+
+ @Override
+ public void removeOnMetadataChangedListener(CachedBluetoothDevice device,
+ BluetoothAdapter.OnMetadataChangedListener listener) {
+
+ }
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
index 2044f05..380c1fc 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
@@ -53,4 +53,4 @@
}
}
-private const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
+internal const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index d653fc7..a633a5e 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -15,12 +15,14 @@
*/
package com.android.systemui.unfold.updates
+import android.content.Context
import android.os.Handler
import android.os.Trace
import android.util.Log
import androidx.annotation.FloatRange
import androidx.annotation.VisibleForTesting
import androidx.core.util.Consumer
+import com.android.systemui.unfold.compat.INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.dagger.UnfoldMain
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
@@ -45,6 +47,7 @@
private val activityTypeProvider: CurrentActivityTypeProvider,
private val unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider,
private val rotationChangeProvider: RotationChangeProvider,
+ private val context: Context,
@UnfoldMain private val mainExecutor: Executor,
@UnfoldMain private val handler: Handler
) : FoldStateProvider {
@@ -119,7 +122,7 @@
"lastHingeAngle: $lastHingeAngle, " +
"lastHingeAngleBeforeTransition: $lastHingeAngleBeforeTransition"
)
- Trace.setCounter( "hinge_angle", angle.toLong())
+ Trace.setCounter("hinge_angle", angle.toLong())
}
val currentDirection =
@@ -136,6 +139,7 @@
val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
val eventNotAlreadyDispatched = lastFoldUpdate != transitionUpdate
val screenAvailableEventSent = isUnfoldHandled
+ val isOnLargeScreen = isOnLargeScreen()
if (
angleChangeSurpassedThreshold && // Do not react immediately to small changes in angle
@@ -144,7 +148,9 @@
// angle range as closing threshold could overlap this range
screenAvailableEventSent && // do not send transition event if we are still in the
// process of turning on the inner display
- isClosingThresholdMet(angle) // hinge angle is below certain threshold.
+ isClosingThresholdMet(angle) && // hinge angle is below certain threshold.
+ isOnLargeScreen // Avoids sending closing event when on small screen.
+ // Start event is sent regardless due to hall sensor.
) {
notifyFoldUpdate(transitionUpdate, lastHingeAngle)
}
@@ -233,7 +239,7 @@
}
private fun cancelAnimation(): Unit =
- notifyFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN, lastHingeAngle)
+ notifyFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN, lastHingeAngle)
private inner class ScreenStatusListener : ScreenStatusProvider.ScreenListener {
@@ -261,6 +267,11 @@
}
}
+ private fun isOnLargeScreen(): Boolean {
+ return context.resources.configuration.smallestScreenWidthDp >
+ INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP
+ }
+
/** While the screen is off or the device is folded, hinge angle updates are not needed. */
private fun updateHingeAngleProviderState() {
if (isScreenOn && !isFolded) {
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index d142f25..8acc508 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -42,7 +42,7 @@
srcs: [
// Include the app source code because the app runs as the system user on-device.
"src/**/*.java",
- "test/src/**/*.java"
+ "test/src/**/*.java",
],
libs: [
"android.test.base",
@@ -54,7 +54,8 @@
"mockito-target-minus-junit4",
"truth-prebuilt",
],
+ resource_dirs: ["test/res"],
certificate: "platform",
platform_apis: true,
- test_suites: ["device-tests"]
+ test_suites: ["device-tests"],
}
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index e549b61..6aca2fd 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -19,11 +19,18 @@
import static android.app.WallpaperManager.FLAG_LOCK;
import static android.app.WallpaperManager.FLAG_SYSTEM;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
+
import android.app.AppGlobals;
import android.app.WallpaperManager;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
import android.app.backup.FullBackupDataOutput;
import android.content.ComponentName;
import android.content.Context;
@@ -103,6 +110,10 @@
private boolean mQuotaExceeded;
private WallpaperManager mWallpaperManager;
+ private WallpaperEventLogger mEventLogger;
+
+ private boolean mSystemHasLiveComponent;
+ private boolean mLockHasLiveComponent;
@Override
public void onCreate() {
@@ -117,6 +128,9 @@
if (DEBUG) {
Slog.v(TAG, "quota file " + mQuotaFile.getPath() + " exists=" + mQuotaExceeded);
}
+
+ BackupManager backupManager = new BackupManager(getApplicationContext());
+ mEventLogger = new WallpaperEventLogger(backupManager, /* wallpaperAgent */ this);
}
@Override
@@ -149,11 +163,18 @@
Slog.v(TAG, "lockGen=" + lockGeneration + " : lockChanged=" + lockChanged);
}
+ // Due to the way image vs live wallpaper backup logic is intermingled, for logging
+ // purposes first check if we have live components for each wallpaper to avoid
+ // over-reporting errors.
+ mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null;
+ mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null;
+
backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data);
backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data);
backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data);
} catch (Exception e) {
Slog.e(TAG, "Unable to back up wallpaper", e);
+ mEventLogger.onBackupException(e);
} finally {
// Even if this time we had to back off on attempting to store the lock image
// due to exceeding the data quota, try again next time. This will alternate
@@ -170,6 +191,14 @@
if (wallpaperInfoFd == null) {
Slog.w(TAG, "Wallpaper metadata file doesn't exist");
+ // If we have live components, getting the file to back up somehow failed, so log it
+ // as an error.
+ if (mSystemHasLiveComponent) {
+ mEventLogger.onSystemLiveWallpaperBackupFailed(ERROR_NO_METADATA);
+ }
+ if (mLockHasLiveComponent) {
+ mEventLogger.onLockLiveWallpaperBackupFailed(ERROR_NO_METADATA);
+ }
return;
}
@@ -182,12 +211,22 @@
if (DEBUG) Slog.v(TAG, "Storing wallpaper metadata");
backupFile(infoStage, data);
+
+ // We've backed up the info file which contains the live component, so log it as success
+ if (mSystemHasLiveComponent) {
+ mEventLogger.onSystemLiveWallpaperBackedUp(
+ mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM));
+ }
+ if (mLockHasLiveComponent) {
+ mEventLogger.onLockLiveWallpaperBackedUp(mWallpaperManager.getWallpaperInfo(FLAG_LOCK));
+ }
}
private void backupSystemWallpaperFile(SharedPreferences sharedPrefs,
boolean sysChanged, int sysGeneration, FullBackupDataOutput data) throws IOException {
if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_SYSTEM)) {
Slog.d(TAG, "System wallpaper ineligible for backup");
+ logSystemImageErrorIfNoLiveComponent(ERROR_INELIGIBLE);
return;
}
@@ -197,6 +236,7 @@
if (systemWallpaperImageFd == null) {
Slog.w(TAG, "System wallpaper doesn't exist");
+ logSystemImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER);
return;
}
@@ -210,8 +250,17 @@
if (DEBUG) Slog.v(TAG, "Storing system wallpaper image");
backupFile(imageStage, data);
sharedPrefs.edit().putInt(SYSTEM_GENERATION, sysGeneration).apply();
+ mEventLogger.onSystemImageWallpaperBackedUp();
}
+ private void logSystemImageErrorIfNoLiveComponent(@BackupRestoreError String error) {
+ if (mSystemHasLiveComponent) {
+ return;
+ }
+ mEventLogger.onSystemImageWallpaperBackupFailed(error);
+ }
+
+
private void backupLockWallpaperFileIfItExists(SharedPreferences sharedPrefs,
boolean lockChanged, int lockGeneration, FullBackupDataOutput data) throws IOException {
final File lockImageStage = new File(getFilesDir(), LOCK_WALLPAPER_STAGE);
@@ -224,11 +273,13 @@
}
Slog.d(TAG, "No lockscreen wallpaper set, add nothing to backup");
sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply();
+ logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER);
return;
}
if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_LOCK)) {
Slog.d(TAG, "Lock screen wallpaper ineligible for backup");
+ logLockImageErrorIfNoLiveComponent(ERROR_INELIGIBLE);
return;
}
@@ -239,11 +290,13 @@
// set, but we can't find it.
if (lockWallpaperFd == null) {
Slog.w(TAG, "Lock wallpaper doesn't exist");
+ logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER);
return;
}
if (mQuotaExceeded) {
Slog.w(TAG, "Not backing up lock screen wallpaper. Quota was exceeded last time");
+ logLockImageErrorIfNoLiveComponent(ERROR_QUOTA_EXCEEDED);
return;
}
@@ -255,6 +308,14 @@
if (DEBUG) Slog.v(TAG, "Storing lock wallpaper image");
backupFile(lockImageStage, data);
sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply();
+ mEventLogger.onLockImageWallpaperBackedUp();
+ }
+
+ private void logLockImageErrorIfNoLiveComponent(@BackupRestoreError String error) {
+ if (mLockHasLiveComponent) {
+ return;
+ }
+ mEventLogger.onLockImageWallpaperBackupFailed(error);
}
/**
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
new file mode 100644
index 0000000..64944b3
--- /dev/null
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2023 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.wallpaperbackup;
+
+import android.annotation.Nullable;
+import android.app.WallpaperInfo;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupRestoreEventLogger;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Log backup / restore related events using {@link BackupRestoreEventLogger}.
+ */
+public class WallpaperEventLogger {
+ /* Static image used as system (or home) screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_IMG_SYSTEM = "wlp_img_system";
+
+ /* Static image used as lock screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_IMG_LOCK = "wlp_img_lock";
+
+ /* Live component used as system (or home) screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_LIVE_SYSTEM = "wlp_live_system";
+
+ /* Live component used as lock screen wallpaper */
+ @BackupRestoreDataType
+ @VisibleForTesting
+ static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock";
+
+ @BackupRestoreError
+ static final String ERROR_INELIGIBLE = "ineligible";
+ @BackupRestoreError
+ static final String ERROR_NO_METADATA = "no_metadata";
+ @BackupRestoreError
+ static final String ERROR_NO_WALLPAPER = "no_wallpaper";
+ @BackupRestoreError
+ static final String ERROR_QUOTA_EXCEEDED = "quota_exceeded";
+
+ private final BackupRestoreEventLogger mLogger;
+
+ private final Set<String> mProcessedDataTypes = new HashSet<>();
+
+ WallpaperEventLogger(BackupManager backupManager, WallpaperBackupAgent wallpaperAgent) {
+ mLogger = backupManager.getBackupRestoreEventLogger(/* backupAgent */ wallpaperAgent);
+ }
+
+ void onSystemImageWallpaperBackedUp() {
+ logBackupSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null);
+ }
+
+ void onLockImageWallpaperBackedUp() {
+ logBackupSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null);
+ }
+
+ void onSystemLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) {
+ logBackupSuccessInternal(WALLPAPER_LIVE_SYSTEM, wallpaperInfo);
+ }
+
+ void onLockLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) {
+ logBackupSuccessInternal(WALLPAPER_LIVE_LOCK, wallpaperInfo);
+ }
+
+ void onSystemImageWallpaperBackupFailed(@BackupRestoreError String error) {
+ logBackupFailureInternal(WALLPAPER_IMG_SYSTEM, error);
+ }
+
+ void onLockImageWallpaperBackupFailed(@BackupRestoreError String error) {
+ logBackupFailureInternal(WALLPAPER_IMG_LOCK, error);
+ }
+
+ void onSystemLiveWallpaperBackupFailed(@BackupRestoreError String error) {
+ logBackupFailureInternal(WALLPAPER_LIVE_SYSTEM, error);
+ }
+
+ void onLockLiveWallpaperBackupFailed(@BackupRestoreError String error) {
+ logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error);
+ }
+
+
+ /**
+ * Called when the whole backup flow is interrupted by an exception.
+ */
+ void onBackupException(Exception exception) {
+ String error = exception.getClass().getName();
+ if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains(
+ WALLPAPER_LIVE_SYSTEM)) {
+ mLogger.logItemsBackupFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error);
+ }
+ if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains(
+ WALLPAPER_LIVE_LOCK)) {
+ mLogger.logItemsBackupFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error);
+ }
+ }
+
+ private void logBackupSuccessInternal(@BackupRestoreDataType String which,
+ @Nullable WallpaperInfo liveComponentWallpaperInfo) {
+ mLogger.logItemsBackedUp(which, /* count */ 1);
+ logLiveWallpaperNameIfPresent(which, liveComponentWallpaperInfo);
+ mProcessedDataTypes.add(which);
+ }
+
+ private void logBackupFailureInternal(@BackupRestoreDataType String which,
+ @BackupRestoreError String error) {
+ mLogger.logItemsBackupFailed(which, /* count */ 1, error);
+ mProcessedDataTypes.add(which);
+ }
+
+ private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType,
+ WallpaperInfo wallpaperInfo) {
+ if (wallpaperInfo != null) {
+ mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName());
+ }
+ }
+}
diff --git a/packages/WallpaperBackup/test/AndroidManifest.xml b/packages/WallpaperBackup/test/AndroidManifest.xml
index 44ab1b6..eb1e98b 100644
--- a/packages/WallpaperBackup/test/AndroidManifest.xml
+++ b/packages/WallpaperBackup/test/AndroidManifest.xml
@@ -4,6 +4,21 @@
<application android:label="WallpaperBackup Tests">
<uses-library android:name="android.test.runner" />
+ <service android:name="com.android.wallpaperbackup.utils.TestWallpaperService"
+ android:enabled="true"
+ android:directBootAware="true"
+ android:label="Test wallpaper"
+ android:permission="android.permission.BIND_WALLPAPER"
+ android:exported="true">
+
+ <intent-filter>
+ <action android:name="android.service.wallpaper.WallpaperService"/>
+ </intent-filter>
+
+ <!-- Link to XML that defines the wallpaper info. -->
+ <meta-data android:name="android.service.wallpaper"
+ android:resource="@xml/livewallpaper"/>
+ </service>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/WallpaperBackup/test/res/xml/livewallpaper.xml b/packages/WallpaperBackup/test/res/xml/livewallpaper.xml
new file mode 100644
index 0000000..c6fbe2bda
--- /dev/null
+++ b/packages/WallpaperBackup/test/res/xml/livewallpaper.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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
+ -->
+<wallpaper/>
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index 20dd5165..89459f6 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -23,22 +23,40 @@
import static com.android.wallpaperbackup.WallpaperBackupAgent.LOCK_WALLPAPER_STAGE;
import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE;
import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER;
+import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_SYSTEM;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.WallpaperInfo;
import android.app.WallpaperManager;
+import android.app.backup.BackupAnnotations;
+import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.app.backup.FullBackupDataOutput;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.service.wallpaper.WallpaperService;
+import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnit4;
@@ -69,12 +87,18 @@
private static final int TEST_SYSTEM_WALLPAPER_ID = 1;
private static final int TEST_LOCK_WALLPAPER_ID = 2;
private static final int NO_LOCK_WALLPAPER_ID = -1;
+ // An arbitrary user.
+ private static final UserHandle USER_HANDLE = new UserHandle(15);
- @Mock private FullBackupDataOutput mOutput;
- @Mock private WallpaperManager mWallpaperManager;
- @Mock private Context mMockContext;
+ @Mock
+ private FullBackupDataOutput mOutput;
+ @Mock
+ private WallpaperManager mWallpaperManager;
+ @Mock
+ private Context mMockContext;
- @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+ @Rule
+ public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
private ContextWithServiceOverrides mContext;
private IsolatedWallpaperBackupAgent mWallpaperBackupAgent;
@@ -90,9 +114,10 @@
mContext = new ContextWithServiceOverrides(ApplicationProvider.getApplicationContext());
mContext.injectSystemService(WallpaperManager.class, mWallpaperManager);
- mWallpaperBackupAgent = new IsolatedWallpaperBackupAgent(mTemporaryFolder.getRoot());
+ mWallpaperBackupAgent = new IsolatedWallpaperBackupAgent();
mWallpaperBackupAgent.attach(mContext);
- mWallpaperBackupAgent.onCreate();
+ mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD,
+ BackupAnnotations.OperationType.BACKUP);
mWallpaperComponent = new ComponentName(TEST_WALLPAPER_PACKAGE, "");
}
@@ -388,6 +413,185 @@
verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK));
}
+ @Test
+ public void testOnFullBackup_systemWallpaperImgSuccess_logsSuccess() throws Exception {
+ mockSystemWallpaperFileWithContents("system wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID);
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void testOnFullBackup_systemWallpaperImgIneligible_logsFailure() throws Exception {
+ when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(false);
+ mockSystemWallpaperFileWithContents("system wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID);
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_INELIGIBLE);
+ }
+
+ @Test
+ public void testOnFullBackup_systemWallpaperImgMissing_logsFailure() throws Exception {
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER);
+ }
+
+ @Test
+ public void testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsLiveSuccess()
+ throws Exception {
+ mockWallpaperInfoFileWithContents("info file");
+ when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo());
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_LIVE_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ assertThat(result.getMetadataHash()).isNotNull();
+ }
+
+ @Test
+ public void testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsNothingForImg()
+ throws Exception {
+ mockWallpaperInfoFileWithContents("info file");
+ when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo());
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNull();
+ }
+
+ @Test
+ public void testOnFullBackup_lockWallpaperImgSuccess_logsSuccess() throws Exception {
+ mockLockWallpaperFileWithContents("lock wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID);
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void testOnFullBackup_lockWallpaperImgIneligible_logsFailure() throws Exception {
+ when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(false);
+ mockLockWallpaperFileWithContents("lock wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID);
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_INELIGIBLE);
+ }
+
+ @Test
+ public void testOnFullBackup_lockWallpaperImgMissing_logsFailure() throws Exception {
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER);
+ }
+
+ @Test
+ public void testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsLiveSuccess()
+ throws Exception {
+ mockWallpaperInfoFileWithContents("info file");
+ when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo());
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_LIVE_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ assertThat(result.getMetadataHash()).isNotNull();
+ }
+
+ @Test
+ public void testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsNothingForImg()
+ throws Exception {
+ mockWallpaperInfoFileWithContents("info file");
+ when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo());
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNull();
+ }
+
+
+ @Test
+ public void testOnFullBackup_exceptionThrown_logsException() throws Exception {
+ when(mWallpaperManager.isWallpaperBackupEligible(anyInt())).thenThrow(
+ new RuntimeException());
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(RuntimeException.class.getName());
+ }
+
+ @Test
+ public void testOnFullBackup_lastBackupOverQuota_logsLockFailure() throws Exception {
+ mockSystemWallpaperFileWithContents("system wallpaper");
+ mockLockWallpaperFileWithContents("lock wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID);
+ markAgentAsOverQuota();
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_QUOTA_EXCEEDED);
+ }
+
+ @Test
+ public void testOnFullBackup_lastBackupOverQuota_logsSystemSuccess() throws Exception {
+ mockSystemWallpaperFileWithContents("system wallpaper");
+ mockLockWallpaperFileWithContents("lock wallpaper");
+ mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID);
+ markAgentAsOverQuota();
+
+ mWallpaperBackupAgent.onFullBackup(mOutput);
+
+ DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
+
private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) {
when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId);
when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId);
@@ -432,16 +636,41 @@
ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY));
}
+ private WallpaperInfo getFakeWallpaperInfo() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+ Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+ intent.setPackage("com.android.wallpaperbackup.tests");
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+ assertEquals(1, result.size());
+ ResolveInfo info = result.get(0);
+ return new WallpaperInfo(context, info);
+ }
+
+ private void markAgentAsOverQuota() throws Exception {
+ // Create over quota file to indicate the last backup was over quota
+ File quotaFile = new File(mContext.getFilesDir(), WallpaperBackupAgent.QUOTA_SENTINEL);
+ quotaFile.createNewFile();
+
+ // Now redo the setup of the agent to pick up the over quota
+ mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD,
+ BackupAnnotations.OperationType.BACKUP);
+ }
+
+ private static DataTypeResult getLoggingResult(String dataType, List<DataTypeResult> results) {
+ for (DataTypeResult result : results) {
+ if ((result.getDataType()).equals(dataType)) {
+ return result;
+ }
+ }
+ return null;
+ }
+
private class IsolatedWallpaperBackupAgent extends WallpaperBackupAgent {
- File mWallpaperBaseDirectory;
List<File> mBackedUpFiles = new ArrayList<>();
PackageMonitor mWallpaperPackageMonitor;
boolean mIsDeviceInRestore = false;
- IsolatedWallpaperBackupAgent(File wallpaperBaseDirectory) {
- mWallpaperBaseDirectory = wallpaperBaseDirectory;
- }
-
@Override
protected void backupFile(File file, FullBackupDataOutput data) {
mBackedUpFiles.add(file);
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
new file mode 100644
index 0000000..3816a3c
--- /dev/null
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2023 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.wallpaperbackup;
+
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_SYSTEM;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.WallpaperInfo;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupRestoreEventLogger;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.service.wallpaper.WallpaperService;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.wallpaperbackup.utils.TestWallpaperService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class WallpaperEventLoggerTest {
+
+ @Mock
+ private BackupRestoreEventLogger mMockLogger;
+
+ @Mock
+ private BackupManager mMockBackupManager;
+
+ @Mock
+ private WallpaperBackupAgent mMockBackupAgent;
+
+ private static final String WALLPAPER_ERROR = "some_error";
+
+ private WallpaperEventLogger mWallpaperEventLogger;
+ private WallpaperInfo mWallpaperInfo;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mMockBackupAgent.getBackupRestoreEventLogger()).thenReturn(mMockLogger);
+ when(mMockBackupManager.getBackupRestoreEventLogger(any())).thenReturn(mMockLogger);
+
+ mWallpaperInfo = getWallpaperInfo();
+ mWallpaperEventLogger = new WallpaperEventLogger(mMockBackupManager, mMockBackupAgent);
+ }
+
+ @Test
+ public void onSystemImgWallpaperBackedUp_logsSuccess() {
+ mWallpaperEventLogger.onSystemImageWallpaperBackedUp();
+
+ verify(mMockLogger).logItemsBackedUp(eq(WALLPAPER_IMG_SYSTEM), eq(1));
+ }
+
+ @Test
+ public void onLockImgWallpaperBackedUp_logsSuccess() {
+ mWallpaperEventLogger.onLockImageWallpaperBackedUp();
+
+ verify(mMockLogger).logItemsBackedUp(eq(WALLPAPER_IMG_LOCK), eq(1));
+ }
+
+ @Test
+ public void onSystemLiveWallpaperBackedUp_logsSuccess() {
+ mWallpaperEventLogger.onSystemLiveWallpaperBackedUp(mWallpaperInfo);
+
+ verify(mMockLogger).logItemsBackedUp(eq(WALLPAPER_LIVE_SYSTEM), eq(1));
+ }
+
+ @Test
+ public void onLockLiveWallpaperBackedUp_logsSuccess() {
+ mWallpaperEventLogger.onLockLiveWallpaperBackedUp(mWallpaperInfo);
+
+ verify(mMockLogger).logItemsBackedUp(eq(WALLPAPER_LIVE_LOCK), eq(1));
+ }
+
+ @Test
+ public void onImgWallpaperBackedUp_nullInfo_doesNotLogMetadata() {
+ mWallpaperEventLogger.onSystemImageWallpaperBackedUp();
+
+ verify(mMockLogger, never()).logBackupMetadata(eq(WALLPAPER_IMG_SYSTEM), anyString());
+ }
+
+
+ @Test
+ public void onLiveWallpaperBackedUp_logsMetadata() {
+ mWallpaperEventLogger.onSystemLiveWallpaperBackedUp(mWallpaperInfo);
+
+ verify(mMockLogger).logBackupMetadata(eq(WALLPAPER_LIVE_SYSTEM),
+ eq(TestWallpaperService.class.getName()));
+ }
+
+
+ @Test
+ public void onSystemImgWallpaperBackupFailed_logsFail() {
+ mWallpaperEventLogger.onSystemImageWallpaperBackupFailed(WALLPAPER_ERROR);
+
+ verify(mMockLogger).logItemsBackupFailed(eq(WALLPAPER_IMG_SYSTEM), eq(1),
+ eq(WALLPAPER_ERROR));
+ }
+
+ @Test
+ public void onLockImgWallpaperBackupFailed_logsFail() {
+ mWallpaperEventLogger.onLockImageWallpaperBackupFailed(WALLPAPER_ERROR);
+
+ verify(mMockLogger).logItemsBackupFailed(eq(WALLPAPER_IMG_LOCK), eq(1),
+ eq(WALLPAPER_ERROR));
+ }
+
+
+ @Test
+ public void onSystemLiveWallpaperBackupFailed_logsFail() {
+ mWallpaperEventLogger.onSystemLiveWallpaperBackupFailed(WALLPAPER_ERROR);
+
+ verify(mMockLogger).logItemsBackupFailed(eq(WALLPAPER_LIVE_SYSTEM), eq(1),
+ eq(WALLPAPER_ERROR));
+ }
+
+ @Test
+ public void onLockLiveWallpaperBackupFailed_logsFail() {
+ mWallpaperEventLogger.onLockLiveWallpaperBackupFailed(WALLPAPER_ERROR);
+
+ verify(mMockLogger).logItemsBackupFailed(eq(WALLPAPER_LIVE_LOCK), eq(1),
+ eq(WALLPAPER_ERROR));
+ }
+
+
+ @Test
+ public void onWallpaperBackupException_someProcessed_doesNotLogErrorForProcessedType() {
+ mWallpaperEventLogger.onSystemImageWallpaperBackedUp();
+
+ mWallpaperEventLogger.onBackupException(new Exception());
+
+ verify(mMockLogger, never()).logItemsBackupFailed(eq(WALLPAPER_IMG_SYSTEM), anyInt(),
+ anyString());
+ }
+
+
+ @Test
+ public void onWallpaperBackupException_someProcessed_logsErrorForUnprocessedType() {
+ mWallpaperEventLogger.onSystemImageWallpaperBackedUp();
+
+ mWallpaperEventLogger.onBackupException(new Exception());
+
+ verify(mMockLogger).logItemsBackupFailed(eq(WALLPAPER_IMG_LOCK), eq(1),
+ eq(Exception.class.getName()));
+
+ }
+
+ @Test
+ public void onWallpaperBackupException_liveTypeProcessed_doesNotLogErrorForSameImgType() {
+ mWallpaperEventLogger.onSystemLiveWallpaperBackedUp(mWallpaperInfo);
+
+ mWallpaperEventLogger.onBackupException(new Exception());
+
+ verify(mMockLogger, never()).logItemsBackupFailed(eq(WALLPAPER_IMG_SYSTEM), anyInt(),
+ anyString());
+ }
+
+ private WallpaperInfo getWallpaperInfo() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+ Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+ intent.setPackage("com.android.wallpaperbackup.tests");
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+ assertEquals(1, result.size());
+ ResolveInfo info = result.get(0);
+ return new WallpaperInfo(context, info);
+ }
+}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/Target01.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/utils/TestWallpaperService.java
similarity index 60%
rename from tests/componentalias/src/android/content/componentalias/tests/b/Target01.java
rename to packages/WallpaperBackup/test/src/com/android/wallpaperbackup/utils/TestWallpaperService.java
index 06f7a13..cb85041 100644
--- a/tests/componentalias/src/android/content/componentalias/tests/b/Target01.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/utils/TestWallpaperService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -13,7 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.componentalias.tests.b;
-public class Target01 extends BaseReceiver {
+package com.android.wallpaperbackup.utils;
+
+import android.service.wallpaper.WallpaperService;
+
+/**
+ * Empty wallpaper service used for wallpaper backup tests
+ */
+public class TestWallpaperService extends WallpaperService {
+ @Override
+ public Engine onCreateEngine() {
+ return new Engine();
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
index fe7b11f..5a783f4 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationThumbnail.java
@@ -63,7 +63,7 @@
private final WindowManager.LayoutParams mBackgroundParams;
private boolean mVisible = false;
- private static final float ASPECT_RATIO = 28f;
+ private static final float ASPECT_RATIO = 14f;
private static final float BG_ASPECT_RATIO = ASPECT_RATIO / 2f;
private ObjectAnimator mThumbNailAnimator;
@@ -261,9 +261,10 @@
mThumbNailView.setScaleY(scaleDown);
}
if (!Float.isNaN(centerX)) {
+ var padding = mThumbNailView.getPaddingTop();
var ratio = 1f / BG_ASPECT_RATIO;
- var centerXScaled = centerX * ratio - mThumbNailView.getWidth() / 2f;
- var centerYScaled = centerY * ratio - mThumbNailView.getHeight() / 2f;
+ var centerXScaled = centerX * ratio - (mThumbNailView.getWidth() / 2f + padding);
+ var centerYScaled = centerY * ratio - (mThumbNailView.getHeight() / 2f + padding);
if (DEBUG) {
Log.d(
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 7d1de40..ca743cb 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -26,6 +26,12 @@
import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_COMMITTED;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__DATASET_AUTHENTICATION;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__FULL_AUTHENTICATION;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU;
@@ -84,6 +90,32 @@
@Retention(RetentionPolicy.SOURCE)
public @interface NotShownReason {}
+ /**
+ * Reasons why presentation was not shown. These are wrappers around
+ * {@link com.android.os.AtomsProto.AutofillPresentationEventReported.AuthenticationType}.
+ */
+ @IntDef(prefix = {"AUTHENTICATION_TYPE"}, value = {
+ AUTHENTICATION_TYPE_UNKNOWN,
+ AUTHENTICATION_TYPE_DATASET_AUTHENTICATION,
+ AUTHENTICATION_TYPE_FULL_AUTHENTICATION
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AuthenticationType {
+ }
+
+ /**
+ * Reasons why presentation was not shown. These are wrappers around
+ * {@link com.android.os.AtomsProto.AutofillPresentationEventReported.AuthenticationResult}.
+ */
+ @IntDef(prefix = {"AUTHENTICATION_RESULT"}, value = {
+ AUTHENTICATION_RESULT_UNKNOWN,
+ AUTHENTICATION_RESULT_SUCCESS,
+ AUTHENTICATION_RESULT_FAILURE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AuthenticationResult {
+ }
+
public static final int NOT_SHOWN_REASON_ANY_SHOWN =
AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__ANY_SHOWN;
public static final int NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED =
@@ -105,6 +137,20 @@
public static final int NOT_SHOWN_REASON_UNKNOWN =
AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
+ public static final int AUTHENTICATION_TYPE_UNKNOWN =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN;
+ public static final int AUTHENTICATION_TYPE_DATASET_AUTHENTICATION =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__DATASET_AUTHENTICATION;
+ public static final int AUTHENTICATION_TYPE_FULL_AUTHENTICATION =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_TYPE__FULL_AUTHENTICATION;
+
+ public static final int AUTHENTICATION_RESULT_UNKNOWN =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN;
+ public static final int AUTHENTICATION_RESULT_SUCCESS =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_SUCCESS;
+ public static final int AUTHENTICATION_RESULT_FAILURE =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE;
+
private final int mSessionId;
private Optional<PresentationStatsEventInternal> mEventInternal;
@@ -146,7 +192,7 @@
}
public void maybeSetAvailableCount(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
mEventInternal.ifPresent(event -> {
int availableCount = getDatasetCountForAutofillId(datasetList, currentViewId);
event.mAvailableCount = availableCount;
@@ -155,7 +201,7 @@
}
public void maybeSetCountShown(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
mEventInternal.ifPresent(event -> {
int countShown = getDatasetCountForAutofillId(datasetList, currentViewId);
event.mCountShown = countShown;
@@ -166,7 +212,7 @@
}
private static int getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
int availableCount = 0;
if (datasetList != null) {
for (int i = 0; i < datasetList.size(); i++) {
@@ -293,6 +339,43 @@
});
}
+ /**
+ * Set authentication_type as long as mEventInternal presents.
+ */
+ public void maybeSetAuthenticationType(@AuthenticationType int val) {
+ mEventInternal.ifPresent(event -> {
+ event.mAuthenticationType = val;
+ });
+ }
+
+ /**
+ * Set authentication_result as long as mEventInternal presents.
+ */
+ public void maybeSetAuthenticationResult(@AuthenticationResult int val) {
+ mEventInternal.ifPresent(event -> {
+ event.mAuthenticationResult = val;
+ });
+ }
+
+ /**
+ * Set latency_authentication_ui_display_millis as long as mEventInternal presents.
+ */
+ public void maybeSetLatencyAuthenticationUiDisplayMillis(int val) {
+ mEventInternal.ifPresent(event -> {
+ event.mLatencyAuthenticationUiDisplayMillis = val;
+ });
+ }
+
+ /**
+ * Set latency_dataset_display_millis as long as mEventInternal presents.
+ */
+ public void maybeSetLatencyDatasetDisplayMillis(int val) {
+ mEventInternal.ifPresent(event -> {
+ event.mLatencyDatasetDisplayMillis = val;
+ });
+ }
+
+
public void logAndEndEvent() {
if (!mEventInternal.isPresent()) {
Slog.w(TAG, "Shouldn't be logging AutofillPresentationEventReported again for same "
@@ -322,7 +405,12 @@
+ " mSelectedDatasetId=" + event.mSelectedDatasetId
+ " mDialogDismissed=" + event.mDialogDismissed
+ " mNegativeCtaButtonClicked=" + event.mNegativeCtaButtonClicked
- + " mPositiveCtaButtonClicked=" + event.mPositiveCtaButtonClicked);
+ + " mPositiveCtaButtonClicked=" + event.mPositiveCtaButtonClicked
+ + " mAuthenticationType=" + event.mAuthenticationType
+ + " mAuthenticationResult=" + event.mAuthenticationResult
+ + " mLatencyAuthenticationUiDisplayMillis="
+ + event.mLatencyAuthenticationUiDisplayMillis
+ + " mLatencyDatasetDisplayMillis=" + event.mLatencyDatasetDisplayMillis);
}
// TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -351,11 +439,15 @@
event.mSelectedDatasetId,
event.mDialogDismissed,
event.mNegativeCtaButtonClicked,
- event.mPositiveCtaButtonClicked);
+ event.mPositiveCtaButtonClicked,
+ event.mAuthenticationType,
+ event.mAuthenticationResult,
+ event.mLatencyAuthenticationUiDisplayMillis,
+ event.mLatencyDatasetDisplayMillis);
mEventInternal = Optional.empty();
}
- private final class PresentationStatsEventInternal {
+ private static final class PresentationStatsEventInternal {
int mRequestId;
@NotShownReason int mNoPresentationReason = NOT_SHOWN_REASON_UNKNOWN;
boolean mIsDatasetAvailable;
@@ -376,6 +468,10 @@
boolean mDialogDismissed = false;
boolean mNegativeCtaButtonClicked = false;
boolean mPositiveCtaButtonClicked = false;
+ int mAuthenticationType = AUTHENTICATION_TYPE_UNKNOWN;
+ int mAuthenticationResult = AUTHENTICATION_RESULT_UNKNOWN;
+ int mLatencyAuthenticationUiDisplayMillis = -1;
+ int mLatencyDatasetDisplayMillis = -1;
PresentationStatsEventInternal() {}
}
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 05b6022..a8519e3 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -128,6 +128,9 @@
* Start listening for incoming messages.
*/
public void start() {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting secure channel.");
+ }
new Thread(() -> {
try {
// 1. Wait for the next handshake message and process it.
@@ -151,14 +154,14 @@
// TODO: Handle different types errors.
Slog.e(TAG, "Secure channel encountered an error.", e);
- stop();
+ close();
mCallback.onError(e);
}
}).start();
}
/**
- * Stop listening to incoming messages and close the channel.
+ * Stop listening to incoming messages.
*/
public void stop() {
if (DEBUG) {
@@ -166,7 +169,17 @@
}
mStopped = true;
mInProgress = false;
+ }
+ /**
+ * Stop listening to incoming messages and close the channel.
+ */
+ public void close() {
+ stop();
+
+ if (DEBUG) {
+ Slog.d(TAG, "Closing secure channel.");
+ }
IoUtils.closeQuietly(mInput);
IoUtils.closeQuietly(mOutput);
KeyStoreUtils.cleanUp(mAlias);
@@ -240,60 +253,64 @@
if (isSecured()) {
Slog.d(TAG, "Waiting to receive next secure message.");
} else {
- Slog.d(TAG, "Waiting to receive next message.");
+ Slog.d(TAG, "Waiting to receive next " + expected + " message.");
}
}
// TODO: Handle message timeout
- // Header is _not_ encrypted, but will be covered by MAC
- final byte[] headerBytes = new byte[HEADER_LENGTH];
- Streams.readFully(mInput, headerBytes);
- final ByteBuffer header = ByteBuffer.wrap(headerBytes);
- final int version = header.getInt();
- final short type = header.getShort();
+ synchronized (mInput) {
+ // Header is _not_ encrypted, but will be covered by MAC
+ final byte[] headerBytes = new byte[HEADER_LENGTH];
+ Streams.readFully(mInput, headerBytes);
+ final ByteBuffer header = ByteBuffer.wrap(headerBytes);
+ final int version = header.getInt();
+ final short type = header.getShort();
- if (version != VERSION) {
- Streams.skipByReading(mInput, Long.MAX_VALUE);
- throw new SecureChannelException("Secure channel version mismatch. "
- + "Currently on version " + VERSION + ". Skipping rest of data.");
+ if (version != VERSION) {
+ Streams.skipByReading(mInput, Long.MAX_VALUE);
+ throw new SecureChannelException("Secure channel version mismatch. "
+ + "Currently on version " + VERSION + ". Skipping rest of data.");
+ }
+
+ if (type != expected.mValue) {
+ Streams.skipByReading(mInput, Long.MAX_VALUE);
+ throw new SecureChannelException(
+ "Unexpected message type. Expected " + expected.name()
+ + "; Found " + MessageType.from(type).name()
+ + ". Skipping rest of data.");
+ }
+
+ // Length of attached data is prepended as plaintext
+ final byte[] lengthBytes = new byte[4];
+ Streams.readFully(mInput, lengthBytes);
+ final int length = ByteBuffer.wrap(lengthBytes).getInt();
+
+ // Read data based on the length
+ final byte[] data;
+ try {
+ data = new byte[length];
+ } catch (OutOfMemoryError error) {
+ throw new SecureChannelException("Payload is too large.", error);
+ }
+
+ Streams.readFully(mInput, data);
+ if (!MessageType.shouldEncrypt(expected)) {
+ return data;
+ }
+
+ return mConnectionContext.decodeMessageFromPeer(data, headerBytes);
}
-
- if (type != expected.mValue) {
- Streams.skipByReading(mInput, Long.MAX_VALUE);
- throw new SecureChannelException("Unexpected message type. Expected " + expected.name()
- + "; Found " + MessageType.from(type).name() + ". Skipping rest of data.");
- }
-
- // Length of attached data is prepended as plaintext
- final byte[] lengthBytes = new byte[4];
- Streams.readFully(mInput, lengthBytes);
- final int length = ByteBuffer.wrap(lengthBytes).getInt();
-
- // Read data based on the length
- final byte[] data;
- try {
- data = new byte[length];
- } catch (OutOfMemoryError error) {
- throw new SecureChannelException("Payload is too large.", error);
- }
-
- Streams.readFully(mInput, data);
- if (!MessageType.shouldEncrypt(expected)) {
- return data;
- }
-
- return mConnectionContext.decodeMessageFromPeer(data, headerBytes);
}
- private void sendMessage(MessageType messageType, byte[] payload)
+ private void sendMessage(MessageType messageType, final byte[] payload)
throws IOException, BadHandleException {
synchronized (mOutput) {
- byte[] header = ByteBuffer.allocate(HEADER_LENGTH)
+ final byte[] header = ByteBuffer.allocate(HEADER_LENGTH)
.putInt(VERSION)
.putShort(messageType.mValue)
.array();
- byte[] data = MessageType.shouldEncrypt(messageType)
+ final byte[] data = MessageType.shouldEncrypt(messageType)
? mConnectionContext.encodeMessageToPeer(payload, header)
: payload;
mOutput.write(header);
diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
index 5390205..092eb4e 100644
--- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
@@ -46,6 +46,7 @@
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -296,26 +297,32 @@
Slog.i(TAG, "Remote device SDK: " + remoteSdk + ", release:" + new String(remoteRelease));
Transport transport = mTempTransport;
- mTempTransport = null;
+ mTempTransport.stop();
int sdk = Build.VERSION.SDK_INT;
String release = Build.VERSION.RELEASE;
- if (remoteSdk == NON_ANDROID) {
+ if (Build.isDebuggable()) {
+ // Debug builds cannot pass attestation verification. Use hardcoded key instead.
+ Slog.d(TAG, "Creating an unauthenticated secure channel");
+ final byte[] testKey = "CDM".getBytes(StandardCharsets.UTF_8);
+ transport = new SecureTransport(transport.getAssociationId(), transport.getFd(),
+ mContext, testKey, null);
+ } else if (remoteSdk == NON_ANDROID) {
// TODO: pass in a real preSharedKey
transport = new SecureTransport(transport.getAssociationId(), transport.getFd(),
- mContext, null, null);
- } else if (sdk < SECURE_CHANNEL_AVAILABLE_SDK
- || remoteSdk < SECURE_CHANNEL_AVAILABLE_SDK) {
- // TODO: depending on the release version, either
- // 1) using a RawTransport for old T versions
- // 2) or an Ukey2 handshaked transport for UKey2 backported T versions
- } else {
+ mContext, new byte[0], null);
+ } else if (sdk >= SECURE_CHANNEL_AVAILABLE_SDK
+ && remoteSdk >= SECURE_CHANNEL_AVAILABLE_SDK) {
Slog.i(TAG, "Creating a secure channel");
transport = new SecureTransport(transport.getAssociationId(), transport.getFd(),
mContext);
- addMessageListenersToTransport(transport);
- transport.start();
+ } else {
+ // TODO: depending on the release version, either
+ // 1) using a RawTransport for old T versions
+ // 2) or an Ukey2 handshaked transport for UKey2 backported T versions
}
+ addMessageListenersToTransport(transport);
+ transport.start();
mTransports.put(transport.getAssociationId(), transport);
// Doesn't need to notifyTransportsChanged here, it'll be done in attachSystemDataTransport
}
diff --git a/services/companion/java/com/android/server/companion/transport/RawTransport.java b/services/companion/java/com/android/server/companion/transport/RawTransport.java
index 4060f6e..4158901 100644
--- a/services/companion/java/com/android/server/companion/transport/RawTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/RawTransport.java
@@ -36,6 +36,9 @@
@Override
public void start() {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting raw transport.");
+ }
new Thread(() -> {
try {
while (!mStopped) {
@@ -44,7 +47,7 @@
} catch (IOException e) {
if (!mStopped) {
Slog.w(TAG, "Trouble during transport", e);
- stop();
+ close();
}
}
}).start();
@@ -52,8 +55,19 @@
@Override
public void stop() {
+ if (DEBUG) {
+ Slog.d(TAG, "Stopping raw transport.");
+ }
mStopped = true;
+ }
+ @Override
+ public void close() {
+ stop();
+
+ if (DEBUG) {
+ Slog.d(TAG, "Closing raw transport.");
+ }
IoUtils.closeQuietly(mRemoteIn);
IoUtils.closeQuietly(mRemoteOut);
}
@@ -79,15 +93,17 @@
}
private void receiveMessage() throws IOException {
- final byte[] headerBytes = new byte[HEADER_LENGTH];
- Streams.readFully(mRemoteIn, headerBytes);
- final ByteBuffer header = ByteBuffer.wrap(headerBytes);
- final int message = header.getInt();
- final int sequence = header.getInt();
- final int length = header.getInt();
- final byte[] data = new byte[length];
- Streams.readFully(mRemoteIn, data);
+ synchronized (mRemoteIn) {
+ final byte[] headerBytes = new byte[HEADER_LENGTH];
+ Streams.readFully(mRemoteIn, headerBytes);
+ final ByteBuffer header = ByteBuffer.wrap(headerBytes);
+ final int message = header.getInt();
+ final int sequence = header.getInt();
+ final int length = header.getInt();
+ final byte[] data = new byte[length];
+ Streams.readFully(mRemoteIn, data);
- handleMessage(message, sequence, data);
+ handleMessage(message, sequence, data);
+ }
}
}
diff --git a/services/companion/java/com/android/server/companion/transport/SecureTransport.java b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
index cca0843..4054fc9 100644
--- a/services/companion/java/com/android/server/companion/transport/SecureTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
@@ -21,6 +21,7 @@
import android.os.ParcelFileDescriptor;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.companion.securechannel.AttestationVerifier;
import com.android.server.companion.securechannel.SecureChannel;
@@ -35,6 +36,7 @@
private volatile boolean mShouldProcessRequests = false;
+ @GuardedBy("mRequestQueue")
private final BlockingQueue<byte[]> mRequestQueue = new ArrayBlockingQueue<>(100);
SecureTransport(int associationId, ParcelFileDescriptor fd, Context context) {
@@ -60,6 +62,12 @@
}
@Override
+ public void close() {
+ mSecureChannel.close();
+ mShouldProcessRequests = false;
+ }
+
+ @Override
public Future<byte[]> requestForResponse(int message, byte[] data) {
// Check if channel is secured and start securing
if (!mShouldProcessRequests) {
@@ -85,12 +93,14 @@
}
// Queue up a message to send
- mRequestQueue.add(ByteBuffer.allocate(HEADER_LENGTH + data.length)
- .putInt(message)
- .putInt(sequence)
- .putInt(data.length)
- .put(data)
- .array());
+ synchronized (mRequestQueue) {
+ mRequestQueue.add(ByteBuffer.allocate(HEADER_LENGTH + data.length)
+ .putInt(message)
+ .putInt(sequence)
+ .putInt(data.length)
+ .put(data)
+ .array());
+ }
}
@Override
@@ -102,9 +112,11 @@
new Thread(() -> {
try {
while (mShouldProcessRequests) {
- byte[] request = mRequestQueue.poll();
- if (request != null) {
- mSecureChannel.sendSecureMessage(request);
+ synchronized (mRequestQueue) {
+ byte[] request = mRequestQueue.poll();
+ if (request != null) {
+ mSecureChannel.sendSecureMessage(request);
+ }
}
}
} catch (IOException e) {
diff --git a/services/companion/java/com/android/server/companion/transport/Transport.java b/services/companion/java/com/android/server/companion/transport/Transport.java
index d69ce89..d30104a 100644
--- a/services/companion/java/com/android/server/companion/transport/Transport.java
+++ b/services/companion/java/com/android/server/companion/transport/Transport.java
@@ -110,13 +110,26 @@
return mFd;
}
+ /**
+ * Start listening to messages.
+ */
public abstract void start();
+
+ /**
+ * Soft stop listening to the incoming data without closing the streams.
+ */
public abstract void stop();
+
+ /**
+ * Stop listening to the incoming data and close the streams.
+ */
+ public abstract void close();
+
protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data)
throws IOException;
/**
- * Send a message
+ * Send a message.
*/
public void sendMessage(int message, @NonNull byte[] data) throws IOException {
sendMessage(message, mNextSequence.incrementAndGet(), data);
@@ -170,7 +183,11 @@
sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, data);
break;
}
- case MESSAGE_REQUEST_PLATFORM_INFO:
+ case MESSAGE_REQUEST_PLATFORM_INFO: {
+ callback(message, data);
+ // DO NOT SEND A RESPONSE!
+ break;
+ }
case MESSAGE_REQUEST_CONTEXT_SYNC: {
callback(message, data);
sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE);
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 742c94a..d6f1348 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -343,10 +343,8 @@
// Check if user is associated with the subscription
if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
Binder.getCallingUserHandle())) {
- if (TelephonyUtils.isUidForeground(mContext, Binder.getCallingUid())) {
- TelephonyUtils.showErrorIfSubscriptionAssociatedWithManagedProfile(mContext,
- subId);
- }
+ TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext,
+ subId, Binder.getCallingUid(), callingPkg);
return;
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 225afea..a60f06a 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4945,10 +4945,6 @@
if (intent.getClipData() == null) {
intent.setClipData(ClipData.newPlainText(null, null));
}
- intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
- | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION));
final long bid = Binder.clearCallingIdentity();
try {
PackageManager pm = mContext.getPackageManager();
@@ -4994,7 +4990,19 @@
if (intent == null) {
return (simulateIntent == null);
}
- return intent.filterEquals(simulateIntent);
+ if (!intent.filterEquals(simulateIntent)) {
+ return false;
+ }
+
+ if (intent.getSelector() != simulateIntent.getSelector()) {
+ return false;
+ }
+
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
+ return (simulateIntent.getFlags() & prohibitedFlags) == 0;
}
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index c129938..461103e 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -7322,7 +7322,7 @@
if (!r.mAllowWhileInUsePermissionInFgs
|| (r.mAllowStartForeground == REASON_DENIED)) {
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, r, backgroundStartPrivileges,
+ callingPackage, callingPid, callingUid, r.app, backgroundStartPrivileges,
isBindService);
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
@@ -7349,7 +7349,7 @@
return true;
}
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, null /* serviceRecord */,
+ callingPackage, callingPid, callingUid, null /* targetProcess */,
BackgroundStartPrivileges.NONE, false);
@ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundNoBindingCheckLocked(
allowWhileInUse, callingPid, callingUid, callingPackage, null /* targetService */,
@@ -7366,13 +7366,14 @@
/**
* Should allow while-in-use permissions in FGS or not.
* A typical BG started FGS is not allowed to have while-in-use permissions.
+ *
* @param callingPackage caller app's package name.
- * @param callingUid caller app's uid.
- * @param targetService the service to start.
+ * @param callingUid caller app's uid.
+ * @param targetProcess the process of the service to start.
* @return {@link ReasonCode}
*/
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
- int callingPid, int callingUid, @Nullable ServiceRecord targetService,
+ int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService) {
int ret = REASON_DENIED;
@@ -7440,8 +7441,8 @@
}
if (ret == REASON_DENIED) {
- if (targetService != null && targetService.app != null) {
- ActiveInstrumentation instr = targetService.app.getActiveInstrumentation();
+ if (targetProcess != null) {
+ ActiveInstrumentation instr = targetProcess.getActiveInstrumentation();
if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
ret = REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
}
@@ -7526,7 +7527,7 @@
final @ReasonCode int allowWhileInUse2 =
shouldAllowFgsWhileInUsePermissionLocked(
clientPackageName,
- clientPid, clientUid, null /* serviceRecord */,
+ clientPid, clientUid, null /* targetProcess */,
BackgroundStartPrivileges.NONE, false);
final @ReasonCode int allowStartFgs =
shouldAllowFgsStartForegroundNoBindingCheckLocked(
@@ -7946,11 +7947,18 @@
boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
String callingPackage) {
return shouldAllowFgsWhileInUsePermissionLocked(callingPackage, callingPid, callingUid,
- /* targetService */ null,
+ /* targetProcess */ null,
BackgroundStartPrivileges.NONE, false)
!= REASON_DENIED;
}
+ boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
+ String callingPackage, @Nullable ProcessRecord targetProcess,
+ @NonNull BackgroundStartPrivileges backgroundStartPrivileges) {
+ return shouldAllowFgsWhileInUsePermissionLocked(callingPackage, callingPid, callingUid,
+ targetProcess, backgroundStartPrivileges, false) != REASON_DENIED;
+ }
+
/**
* Checks if a given packageName belongs to a given uid.
* @param packageName the package of the caller
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 4fa28a1..82c4796a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -118,6 +118,8 @@
static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit";
static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration";
static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration";
+ static final String KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION =
+ "vis_to_invis_uij_schedule_grace_duration";
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate";
static final String KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE = "fgs_start_allowed_log_sample_rate";
@@ -191,6 +193,8 @@
private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12;
private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 20 * 1000;
private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
+ private static final long DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION =
+ DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 %
private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25%
@@ -680,6 +684,15 @@
volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
/**
+ * The grace period in milliseconds to allow a process to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}
+ * after switching from visible to a non-visible state.
+ * Currently it's only applicable to its activities.
+ */
+ volatile long mVisibleToInvisibleUijScheduleGraceDurationMs =
+ DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION;
+
+ /**
* When service started from background, before the timeout it can be promoted to FGS by calling
* Service.startForeground().
*/
@@ -1123,6 +1136,9 @@
case KEY_FG_TO_BG_FGS_GRACE_DURATION:
updateFgToBgFgsGraceDuration();
break;
+ case KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION:
+ updateFgToBgFgsGraceDuration();
+ break;
case KEY_FGS_START_FOREGROUND_TIMEOUT:
updateFgsStartForegroundTimeout();
break;
@@ -1598,6 +1614,13 @@
DEFAULT_FG_TO_BG_FGS_GRACE_DURATION);
}
+ private void updateVisibleToInvisibleUijScheduleGraceDuration() {
+ mVisibleToInvisibleUijScheduleGraceDurationMs = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION,
+ DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION);
+ }
+
private void updateFgsStartForegroundTimeout() {
mFgsStartForegroundTimeoutMs = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9e5acf7..32c9a09 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -23,6 +23,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
import static android.Manifest.permission.MANAGE_USERS;
+import static android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.app.ActivityManager.INSTR_FLAG_ALWAYS_CHECK_SIGNATURE;
@@ -32,6 +33,7 @@
import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART;
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -60,9 +62,22 @@
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
+import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
+import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_TOP;
+import static android.os.PowerExemptionManager.REASON_START_ACTIVITY_FLAG;
+import static android.os.PowerExemptionManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED;
+import static android.os.PowerExemptionManager.REASON_SYSTEM_UID;
+import static android.os.PowerExemptionManager.REASON_UID_VISIBLE;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
+import static android.os.PowerExemptionManager.getReasonCodeFromProcState;
import static android.os.Process.BLUETOOTH_UID;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.INVALID_UID;
@@ -167,6 +182,7 @@
import android.annotation.Nullable;
import android.annotation.PermissionMethod;
import android.annotation.PermissionName;
+import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityClient;
@@ -6541,6 +6557,143 @@
}
/**
+ * Returns true if the reasonCode is included in the base set of reasons an app may be
+ * allowed to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ * This is a shortcut and <b>DOES NOT</b> include all reasons.
+ * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases.
+ */
+ private boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) {
+ switch (reasonCode) {
+ case REASON_PROC_STATE_PERSISTENT:
+ case REASON_PROC_STATE_PERSISTENT_UI:
+ case REASON_PROC_STATE_TOP:
+ case REASON_PROC_STATE_BTOP:
+ case REASON_UID_VISIBLE:
+ case REASON_SYSTEM_UID:
+ case REASON_START_ACTIVITY_FLAG:
+ case REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD:
+ case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
+ case REASON_COMPANION_DEVICE_MANAGER:
+ case REASON_BACKGROUND_ACTIVITY_PERMISSION:
+ case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the ProcessRecord has some conditions that allow the app to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ * This is a shortcut and <b>DOES NOT</b> include all reasons.
+ * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases.
+ */
+ @GuardedBy(anyOf = {"this", "mProcLock"})
+ private boolean isProcessInStateToScheduleUserInitiatedJobsLocked(
+ @Nullable ProcessRecord pr, long nowElapsed) {
+ if (pr == null) {
+ return false;
+ }
+
+ final BackgroundStartPrivileges backgroundStartPrivileges =
+ pr.getBackgroundStartPrivileges();
+ // Is the allow activity background start flag on?
+ if (backgroundStartPrivileges.allowsBackgroundActivityStarts()) {
+ // REASON_START_ACTIVITY_FLAG;
+ return true;
+ }
+
+ final ProcessStateRecord state = pr.mState;
+ final int procstate = state.getCurProcState();
+ if (procstate <= PROCESS_STATE_BOUND_TOP) {
+ if (doesReasonCodeAllowSchedulingUserInitiatedJobs(
+ getReasonCodeFromProcState(procstate))) {
+ return true;
+ }
+ }
+
+ final long lastInvisibleTime = state.getLastInvisibleTime();
+ if (lastInvisibleTime > 0 && lastInvisibleTime < Long.MAX_VALUE) {
+ final long timeSinceVisibleMs = nowElapsed - lastInvisibleTime;
+ if (timeSinceVisibleMs < mConstants.mVisibleToInvisibleUijScheduleGraceDurationMs) {
+ // REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether the app in question is in a state where we allow scheduling a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ */
+ // TODO(262260570): log allow reason to an atom
+ private boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ synchronized (this) {
+ final ProcessRecord processRecord;
+ synchronized (mPidsSelfLocked) {
+ processRecord = mPidsSelfLocked.get(pid);
+ }
+
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ final BackgroundStartPrivileges backgroundStartPrivileges;
+ if (processRecord != null) {
+ if (isProcessInStateToScheduleUserInitiatedJobsLocked(processRecord, nowElapsed)) {
+ return true;
+ }
+ backgroundStartPrivileges = processRecord.getBackgroundStartPrivileges();
+ } else {
+ backgroundStartPrivileges = getBackgroundStartPrivileges(uid);
+ }
+ // Is the allow activity background start flag on?
+ if (backgroundStartPrivileges.allowsBackgroundActivityStarts()) {
+ // REASON_START_ACTIVITY_FLAG;
+ return true;
+ }
+
+ // We allow scheduling a user-initiated job when the app is in the TOP or a
+ // Background Activity Launch approved state. These are cases that indicate the user
+ // has interacted with the app and therefore it is reasonable to believe the app may
+ // attempt to schedule a user-initiated job in response to the user interaction.
+ // As of Android UDC, the conditions required to grant a while-in-use permission
+ // covers the majority of those cases, and so we piggyback on that logic as the base.
+ // Missing cases are added after.
+ if (mServices.canAllowWhileInUsePermissionInFgsLocked(
+ pid, uid, pkgName, processRecord, backgroundStartPrivileges)) {
+ return true;
+ }
+
+ final UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid);
+ if (uidRecord != null) {
+ for (int i = uidRecord.getNumOfProcs() - 1; i >= 0; --i) {
+ ProcessRecord pr = uidRecord.getProcessRecordByIndex(i);
+ if (isProcessInStateToScheduleUserInitiatedJobsLocked(pr, nowElapsed)) {
+ return true;
+ }
+ }
+ }
+
+ if (mAtmInternal.hasSystemAlertWindowPermission(uid, pid, pkgName)) {
+ // REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+ return true;
+ }
+
+ final int userId = UserHandle.getUserId(uid);
+ final boolean isCompanionApp = mInternal.isAssociatedCompanionApp(userId, uid);
+ if (isCompanionApp) {
+ if (checkPermission(REQUEST_COMPANION_RUN_IN_BACKGROUND, pid, uid)
+ == PERMISSION_GRANTED) {
+ // REASON_COMPANION_DEVICE_MANAGER;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
* @return allowlist tag for a uid from mPendingTempAllowlist, null if not currently on
* the allowlist
*/
@@ -7773,10 +7926,15 @@
*
* @param callback remote callback object to be registered
*/
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @Override
public void registerUidFrozenStateChangedCallback(
@NonNull IUidFrozenStateChangedCallback callback) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "registerUidFrozenStateChangedCallback()");
+ Preconditions.checkNotNull(callback, "callback cannot be null");
synchronized (mUidFrozenStateChangedCallbackList) {
- boolean registered = mUidFrozenStateChangedCallbackList.register(callback);
+ final boolean registered = mUidFrozenStateChangedCallbackList.register(callback);
if (!registered) {
Slog.w(TAG, "Failed to register with RemoteCallbackList!");
}
@@ -7788,8 +7946,13 @@
*
* @param callback remote callback object to be unregistered
*/
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @Override
public void unregisterUidFrozenStateChangedCallback(
@NonNull IUidFrozenStateChangedCallback callback) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "unregisterUidFrozenStateChangedCallback()");
+ Preconditions.checkNotNull(callback, "callback cannot be null");
synchronized (mUidFrozenStateChangedCallbackList) {
mUidFrozenStateChangedCallbackList.unregister(callback);
}
@@ -18156,6 +18319,11 @@
return ActivityManagerService.this.getBackgroundStartPrivileges(uid);
}
+ @Override
+ public boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ return ActivityManagerService.this.canScheduleUserInitiatedJobs(uid, pid, pkgName);
+ }
+
public void reportCurKeyguardUsageEvent(boolean keyguardShowing) {
ActivityManagerService.this.reportGlobalUsageEvent(keyguardShowing
? UsageEvents.Event.KEYGUARD_SHOWN
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 7c84b72..d9ba845 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -66,6 +66,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.WakeLockStats;
import android.os.WorkSource;
@@ -140,6 +141,7 @@
BatteryStatsImpl.EnergyStatsRetriever,
Watchdog.Monitor {
static final String TAG = "BatteryStatsService";
+ static final String TRACE_TRACK_WAKEUP_REASON = "wakeup_reason";
static final boolean DBG = false;
private static final boolean BATTERY_USAGE_STORE_ENABLED = true;
@@ -2482,6 +2484,10 @@
while ((reason = waitWakeup()) != null) {
final long nowElapsed = SystemClock.elapsedRealtime();
final long nowUptime = SystemClock.uptimeMillis();
+
+ Trace.instantForTrack(Trace.TRACE_TAG_POWER, TRACE_TRACK_WAKEUP_REASON,
+ nowElapsed + " " + reason);
+
// Wait for the completion of pending works if there is any
awaitCompletion();
mCpuWakeupStats.noteWakeupTimeAndReason(nowElapsed, nowUptime, reason);
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index e8b65b8..2617fb7 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -1233,7 +1233,7 @@
}
UidRecord uidRec = app.getUidRecord();
- if (uidRec.isFrozen()) {
+ if (uidRec != null && uidRec.isFrozen()) {
uidRec.setFrozen(false);
mFreezeHandler.removeMessages(UID_FROZEN_STATE_CHANGED_MSG, app);
reportOneUidFrozenStateChanged(app.uid, false);
diff --git a/services/core/java/com/android/server/am/ComponentAliasResolver.java b/services/core/java/com/android/server/am/ComponentAliasResolver.java
index 01735a7..f9eaf02 100644
--- a/services/core/java/com/android/server/am/ComponentAliasResolver.java
+++ b/services/core/java/com/android/server/am/ComponentAliasResolver.java
@@ -30,7 +30,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
-import android.os.Build;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -43,7 +42,6 @@
import com.android.internal.os.BackgroundThread;
import com.android.server.FgThread;
import com.android.server.LocalServices;
-import com.android.server.compat.CompatChange;
import com.android.server.compat.PlatformCompat;
import java.io.PrintWriter;
@@ -52,26 +50,11 @@
import java.util.function.Supplier;
/**
- * Manages and handles component aliases, which is an experimental feature.
+ * @deprecated This feature is no longer used. Delete this class.
*
- * NOTE: THIS CLASS IS PURELY EXPERIMENTAL AND WILL BE REMOVED IN FUTURE ANDROID VERSIONS.
- * DO NOT USE IT.
- *
- * "Component alias" allows an android manifest component (for now only broadcasts and services)
- * to be defined in one android package while having the implementation in a different package.
- *
- * When/if this becomes a real feature, it will be most likely implemented very differently,
- * which is why this shouldn't be used.
- *
- * For now, because this is an experimental feature to evaluate feasibility, the implementation is
- * "quick & dirty". For example, to define aliases, we use a regular intent filter and meta-data
- * in the manifest, instead of adding proper tags/attributes to AndroidManifest.xml.
- *
- * This feature is disabled by default.
- *
- * Also, for now, aliases can be defined across packages with different certificates, but
- * in a final version this will most likely be tightened.
+ * Also delete Intnt.(set|get)OriginalIntent.
*/
+@Deprecated
public class ComponentAliasResolver {
private static final String TAG = "ComponentAliasResolver";
private static final boolean DEBUG = true;
@@ -149,11 +132,6 @@
}
};
- private final CompatChange.ChangeListener mCompatChangeListener = (packageName) -> {
- if (DEBUG) Slog.d(TAG, "USE_EXPERIMENTAL_COMPONENT_ALIAS changed.");
- BackgroundThread.getHandler().post(this::refresh);
- };
-
/**
* Call this on systemRead().
*/
@@ -161,8 +139,6 @@
synchronized (mLock) {
mPlatformCompat = (PlatformCompat) ServiceManager.getService(
Context.PLATFORM_COMPAT_SERVICE);
- mPlatformCompat.registerListener(USE_EXPERIMENTAL_COMPONENT_ALIAS,
- mCompatChangeListener);
}
if (DEBUG) Slog.d(TAG, "Compat listener set.");
update(enabledByDeviceConfig, overrides);
@@ -176,10 +152,8 @@
if (mPlatformCompat == null) {
return; // System not ready.
}
- final boolean enabled = Build.isDebuggable()
- && (enabledByDeviceConfig
- || mPlatformCompat.isChangeEnabledByPackageName(
- USE_EXPERIMENTAL_COMPONENT_ALIAS, "android", UserHandle.USER_SYSTEM));
+ // Never enable it.
+ final boolean enabled = false;
if (enabled != mEnabled) {
Slog.i(TAG, (enabled ? "Enabling" : "Disabling") + " component aliases...");
FgThread.getHandler().post(() -> {
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index a944f6f..7a92434 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -2048,8 +2048,9 @@
// around switching between two apps. However, we don't want to keep the
// process in this privileged state indefinitely. Eventually, allow the
// app to be demoted to cached.
- if ((state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
- && (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now)) {
+ if (procState >= PROCESS_STATE_LAST_ACTIVITY
+ && state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
+ && (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now) {
procState = PROCESS_STATE_LAST_ACTIVITY;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("previous-expired");
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index e38e8c1..e39ac2b 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -311,6 +311,11 @@
}
@GuardedBy(anyOf = {"mService", "mProcLock"})
+ ProcessRecord getProcessRecordByIndex(int idx) {
+ return mProcRecords.valueAt(idx);
+ }
+
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
ProcessRecord getProcessInPackage(String packageName) {
for (int i = mProcRecords.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcRecords.valueAt(i);
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fc22935..965a07b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -157,10 +157,10 @@
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemServiceManager;
import com.android.server.pm.PackageList;
+import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
-import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedAttribution;
import com.android.server.policy.AppOpsPolicy;
@@ -367,6 +367,9 @@
/** Package Manager internal. Access via {@link #getPackageManagerInternal()} */
private @Nullable PackageManagerInternal mPackageManagerInternal;
+ /** Package Manager local. Access via {@link #getPackageManagerLocal()} */
+ private @Nullable PackageManagerLocal mPackageManagerLocal;
+
/** User Manager internal. Access via {@link #getUserManagerInternal()} */
private @Nullable UserManagerInternal mUserManagerInternal;
@@ -1189,42 +1192,64 @@
/**
* Initialize uid state objects for state contained in the checking service.
*/
- private void initializeUidStates() {
+ @VisibleForTesting
+ void initializeUidStates() {
UserManagerInternal umi = getUserManagerInternal();
- int[] userIds = umi.getUserIds();
synchronized (this) {
- for (int i = 0; i < userIds.length; i++) {
- int userId = userIds[i];
- initializeUserUidStatesLocked(userId);
+ int[] userIds = umi.getUserIds();
+ try (PackageManagerLocal.UnfilteredSnapshot snapshot =
+ getPackageManagerLocal().withUnfilteredSnapshot()) {
+ Map<String, PackageState> packageStates = snapshot.getPackageStates();
+ for (int i = 0; i < userIds.length; i++) {
+ int userId = userIds[i];
+ initializeUserUidStatesLocked(userId, packageStates);
+ }
}
}
}
private void initializeUserUidStates(int userId) {
synchronized (this) {
- initializeUserUidStatesLocked(userId);
+ try (PackageManagerLocal.UnfilteredSnapshot snapshot =
+ getPackageManagerLocal().withUnfilteredSnapshot()) {
+ initializeUserUidStatesLocked(userId, snapshot.getPackageStates());
+ }
}
}
- private void initializeUserUidStatesLocked(int userId) {
- ArrayMap<String, ? extends PackageStateInternal> packageStates =
- getPackageManagerInternal().getPackageStates();
- for (int j = 0; j < packageStates.size(); j++) {
- PackageStateInternal packageState = packageStates.valueAt(j);
- int uid = UserHandle.getUid(userId, packageState.getAppId());
- UidState uidState = getUidStateLocked(uid, true);
- String packageName = packageStates.keyAt(j);
- Ops ops = new Ops(packageName, uidState);
- uidState.pkgOps.put(packageName, ops);
+ private void initializeUserUidStatesLocked(int userId, Map<String,
+ PackageState> packageStates) {
+ for (Map.Entry<String, PackageState> entry : packageStates.entrySet()) {
+ int appId = entry.getValue().getAppId();
+ String packageName = entry.getKey();
- SparseIntArray packageModes =
- mAppOpsCheckingService.getNonDefaultPackageModes(packageName, userId);
- for (int k = 0; k < packageModes.size(); k++) {
- int code = packageModes.get(k);
+ initializePackageUidStateLocked(userId, appId, packageName);
+ }
+ }
+
+ /*
+ Be careful not to clear any existing data; only want to add objects that don't already exist.
+ */
+ private void initializePackageUidStateLocked(int userId, int appId, String packageName) {
+ int uid = UserHandle.getUid(userId, appId);
+ UidState uidState = getUidStateLocked(uid, true);
+ Ops ops = uidState.pkgOps.get(packageName);
+ if (ops == null) {
+ ops = new Ops(packageName, uidState);
+ uidState.pkgOps.put(packageName, ops);
+ }
+
+ SparseIntArray packageModes =
+ mAppOpsCheckingService.getNonDefaultPackageModes(packageName, userId);
+ for (int k = 0; k < packageModes.size(); k++) {
+ int code = packageModes.keyAt(k);
+
+ if (ops.indexOfKey(code) < 0) {
ops.put(code, new Op(uidState, packageName, code, uid));
}
- uidState.evalForegroundOps();
}
+
+ uidState.evalForegroundOps();
}
/**
@@ -3649,6 +3674,20 @@
}
/**
+ * @return {@link PackageManagerLocal}
+ */
+ private @NonNull PackageManagerLocal getPackageManagerLocal() {
+ if (mPackageManagerLocal == null) {
+ mPackageManagerLocal = LocalManagerRegistry.getManager(PackageManagerLocal.class);
+ }
+ if (mPackageManagerLocal == null) {
+ throw new IllegalStateException("PackageManagerLocal not loaded");
+ }
+
+ return mPackageManagerLocal;
+ }
+
+ /**
* @return {@link UserManagerInternal}
*/
private @NonNull UserManagerInternal getUserManagerInternal() {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4e687f4..5893f1e 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -16,6 +16,7 @@
package com.android.server.audio;
+import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED;
import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK;
import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
@@ -170,6 +171,7 @@
import android.provider.Settings.System;
import android.service.notification.ZenModeConfig;
import android.telecom.TelecomManager;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
@@ -184,6 +186,7 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -311,7 +314,7 @@
* volumes will be updated in case of a change.
* @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
*/
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void setNotifAliasRingForTest(boolean alias) {
super.setNotifAliasRingForTest_enforcePermission();
boolean update = (mNotifAliasRing != alias);
@@ -393,6 +396,7 @@
private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
private static final int MSG_LOWER_VOLUME_TO_RS1 = 53;
+ private static final int MSG_CONFIGURATION_CHANGED = 54;
/** Messages handled by the {@link SoundDoseHelper}. */
/*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
@@ -1219,17 +1223,6 @@
updateAudioHalPids();
- boolean cameraSoundForced = readCameraSoundForced();
- mCameraSoundForced = new Boolean(cameraSoundForced);
- sendMsg(mAudioHandler,
- MSG_SET_FORCE_USE,
- SENDMSG_QUEUE,
- AudioSystem.FOR_SYSTEM,
- cameraSoundForced ?
- AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
- new String("AudioService ctor"),
- 0);
-
mUseFixedVolume = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
@@ -1314,6 +1307,18 @@
* Called by handling of MSG_INIT_STREAMS_VOLUMES
*/
private void onInitStreamsAndVolumes() {
+ synchronized (mSettingsLock) {
+ mCameraSoundForced = readCameraSoundForced();
+ sendMsg(mAudioHandler,
+ MSG_SET_FORCE_USE,
+ SENDMSG_QUEUE,
+ AudioSystem.FOR_SYSTEM,
+ mCameraSoundForced
+ ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
+ new String("AudioService ctor"),
+ 0);
+ }
+
createStreamStates();
// must be called after createStreamStates() as it uses MUSIC volume as default if no
@@ -1349,8 +1354,19 @@
// check on volume initialization
checkVolumeRangeInitialization("AudioService()");
+
}
+ private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
+ new SubscriptionManager.OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ Log.i(TAG, "onSubscriptionsChanged()");
+ sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE,
+ 0, 0, null, 0);
+ }
+ };
+
/**
* Initialize intent receives and settings observers for this service.
* Must be called after createStreamStates() as the handling of some events
@@ -1388,6 +1404,13 @@
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null,
Context.RECEIVER_EXPORTED);
+ SubscriptionManager subscriptionManager = mContext.getSystemService(
+ SubscriptionManager.class);
+ if (subscriptionManager == null) {
+ Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!");
+ } else {
+ subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener);
+ }
}
public void systemReady() {
@@ -3665,7 +3688,7 @@
for (int stream = 0; stream < mStreamStates.length; stream++) {
VolumeStreamState vss = mStreamStates[stream];
if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
- if (!(readCameraSoundForced()
+ if (!(mCameraSoundForced
&& (vss.getStreamType()
== AudioSystem.STREAM_SYSTEM_ENFORCED))) {
boolean changed = vss.mute(state, /* apply= */ false);
@@ -3845,7 +3868,7 @@
@Override
@android.annotation.EnforcePermission(anyOf = {
- android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED,
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
/** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
@@ -3892,7 +3915,7 @@
@Override
@android.annotation.EnforcePermission(anyOf = {
- android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED,
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
/** @see AudioManager#getVolumeGroupVolumeIndex(int) */
@@ -3911,7 +3934,7 @@
/** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
@android.annotation.EnforcePermission(anyOf = {
- android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED,
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMaxVolumeIndex(int groupId) {
@@ -3927,7 +3950,7 @@
/** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
@android.annotation.EnforcePermission(anyOf = {
- android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED,
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED,
android.Manifest.permission.MODIFY_AUDIO_ROUTING
})
public int getVolumeGroupMinVolumeIndex(int groupId) {
@@ -5053,7 +5076,7 @@
* @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable)
* @see AudioManager#removeOnStreamAliasingChangedListener(Runnable)
*/
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) {
super.registerStreamAliasingDispatcher_enforcePermission();
Objects.requireNonNull(isad);
@@ -5081,7 +5104,7 @@
* @see AudioManager#getIndependentStreamTypes()
* @return the list of non-aliased stream types
*/
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public ArrayList<Integer> getIndependentStreamTypes() {
super.getIndependentStreamTypes_enforcePermission();
@@ -5103,7 +5126,7 @@
* @param sourceStreamType the stream type for which the alias is queried
* @return the stream alias
*/
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public @AudioManager.PublicStreamTypes
int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) {
super.getStreamTypeAlias_enforcePermission();
@@ -5118,7 +5141,7 @@
* @return true when volume control is performed through volume groups, false if it uses
* stream types.
*/
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public boolean isVolumeControlUsingVolumeGroups() {
super.isVolumeControlUsingVolumeGroups_enforcePermission();
@@ -9237,6 +9260,10 @@
onLowerVolumeToRs1();
break;
+ case MSG_CONFIGURATION_CHANGED:
+ onConfigurationChanged();
+ break;
+
default:
if (msg.what >= SAFE_MEDIA_VOLUME_MSG_START) {
// msg could be for the SoundDoseHelper
@@ -9419,7 +9446,12 @@
}
AudioSystem.setParameters("screen_state=off");
} else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
- handleConfigurationChanged(context);
+ sendMsg(mAudioHandler,
+ MSG_CONFIGURATION_CHANGED,
+ SENDMSG_REPLACE,
+ 0,
+ 0,
+ null, 0);
} else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
if (mUserSwitchedReceived) {
// attempt to stop music playback for background user except on first user
@@ -10161,10 +10193,30 @@
}
//==========================================================================================
+
+ // camera sound is forced if any of the resources corresponding to one active SIM
+ // demands it.
private boolean readCameraSoundForced() {
- return SystemProperties.getBoolean("audio.camerasound.force", false) ||
- mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_camera_sound_forced);
+ if (SystemProperties.getBoolean("audio.camerasound.force", false)
+ || mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_camera_sound_forced)) {
+ return true;
+ }
+
+ SubscriptionManager subscriptionManager = mContext.getSystemService(
+ SubscriptionManager.class);
+ if (subscriptionManager == null) {
+ Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!");
+ return false;
+ }
+ int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false);
+ for (int subId : subscriptionIds) {
+ if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean(
+ com.android.internal.R.bool.config_camera_sound_forced)) {
+ return true;
+ }
+ }
+ return false;
}
//==========================================================================================
@@ -10375,11 +10427,11 @@
* Monitoring rotation is optional, and is defined by the definition and value
* of the "ro.audio.monitorRotation" system property.
*/
- private void handleConfigurationChanged(Context context) {
+ private void onConfigurationChanged() {
try {
// reading new configuration "safely" (i.e. under try catch) in case anything
// goes wrong.
- Configuration config = context.getResources().getConfiguration();
+ Configuration config = mContext.getResources().getConfiguration();
mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG);
boolean cameraSoundForced = readCameraSoundForced();
@@ -10406,7 +10458,7 @@
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
cameraSoundForced ?
AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
- "handleConfigurationChanged");
+ "onConfigurationChanged");
sendMsg(mAudioHandler,
MSG_SET_ALL_VOLUMES,
SENDMSG_QUEUE,
@@ -10477,49 +10529,53 @@
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public float getOutputRs2UpperBound() {
super.getOutputRs2UpperBound_enforcePermission();
return mSoundDoseHelper.getOutputRs2UpperBound();
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void setOutputRs2UpperBound(float rs2Value) {
super.setOutputRs2UpperBound_enforcePermission();
mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public float getCsd() {
super.getCsd_enforcePermission();
return mSoundDoseHelper.getCsd();
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void setCsd(float csd) {
super.setCsd_enforcePermission();
- mSoundDoseHelper.setCsd(csd);
+ if (csd < 0.0f) {
+ mSoundDoseHelper.resetCsdTimeouts();
+ } else {
+ mSoundDoseHelper.setCsd(csd);
+ }
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void forceUseFrameworkMel(boolean useFrameworkMel) {
super.forceUseFrameworkMel_enforcePermission();
mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel);
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
super.forceComputeCsdOnAllDevices_enforcePermission();
mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices);
}
@Override
- @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+ @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public boolean isCsdEnabled() {
super.isCsdEnabled_enforcePermission();
return mSoundDoseHelper.isCsdEnabled();
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index bb49a18..31f0c05 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -21,6 +21,8 @@
import static com.android.server.audio.AudioService.MSG_SET_DEVICE_VOLUME;
import static com.android.server.audio.AudioService.SAFE_MEDIA_VOLUME_MSG_START;
+import static java.lang.Math.floor;
+
import android.annotation.NonNull;
import android.app.AlarmManager;
import android.app.PendingIntent;
@@ -94,6 +96,8 @@
private static final int MOMENTARY_EXPOSURE_TIMEOUT_MS = (20 * 3600 * 1000); // 20 hours
+ private static final int MOMENTARY_EXPOSURE_TIMEOUT_UNINITIALIZED = -1;
+
// 30s after boot completed
private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;
@@ -147,6 +151,9 @@
*/
private final SparseIntArray mSafeMediaVolumeDevices = new SparseIntArray();
+ /** Used for testing to enforce safe media on all devices */
+ private boolean mForceSafeMediaOnAllDevices = false;
+
// mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
// When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
// automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
@@ -170,7 +177,7 @@
private float mCurrentCsd = 0.f;
@GuardedBy("mCsdStateLock")
- private long mLastMomentaryExposureTimeMs = -1;
+ private long mLastMomentaryExposureTimeMs = MOMENTARY_EXPOSURE_TIMEOUT_UNINITIALIZED;
// dose at which the next dose reached warning occurs
@GuardedBy("mCsdStateLock")
@@ -364,12 +371,13 @@
SoundDoseRecord[] doseRecordsArray;
synchronized (mCsdStateLock) {
mCurrentCsd = csd;
+ mNextCsdWarning = (float) floor(csd + 1.0);
mDoseRecords.clear();
if (mCurrentCsd > 0.0f) {
final SoundDoseRecord record = new SoundDoseRecord();
- record.timestamp = SystemClock.elapsedRealtime();
+ record.timestamp = SystemClock.elapsedRealtime() / 1000;
record.value = csd;
mDoseRecords.add(record);
}
@@ -389,6 +397,22 @@
}
}
+ void resetCsdTimeouts() {
+ if (!mEnableCsd) {
+ return;
+ }
+
+ synchronized (mSafeMediaVolumeStateLock) {
+ mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
+ mMusicActiveMs = 0;
+ saveMusicActiveMs();
+ }
+
+ synchronized (mCsdStateLock) {
+ mLastMomentaryExposureTimeMs = MOMENTARY_EXPOSURE_TIMEOUT_UNINITIALIZED;
+ }
+ }
+
void forceUseFrameworkMel(boolean useFrameworkMel) {
if (!mEnableCsd) {
return;
@@ -423,10 +447,27 @@
} catch (RemoteException e) {
Log.e(TAG, "Exception while forcing CSD computation on all devices", e);
}
+
+ mForceSafeMediaOnAllDevices = computeCsdOnAllDevices;
}
boolean isCsdEnabled() {
- return mEnableCsd;
+ if (!mEnableCsd) {
+ return false;
+ }
+
+ final ISoundDose soundDose = mSoundDose.get();
+ if (soundDose == null) {
+ Log.w(TAG, "Sound dose interface not initialized");
+ return false;
+ }
+
+ try {
+ return soundDose.isSoundDoseHalSupported();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while forcing CSD computation on all devices", e);
+ }
+ return false;
}
/*package*/ int safeMediaVolumeIndex(int device) {
@@ -490,7 +531,7 @@
private boolean checkSafeMediaVolume_l(int streamType, int index, int device) {
return (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)
&& (AudioService.mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC)
- && safeDevicesContains(device)
+ && (safeDevicesContains(device) || mForceSafeMediaOnAllDevices)
&& (index > safeMediaVolumeIndex(device));
}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContext.java b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
index 9199acb..79ce6b4 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.common.OperationContext;
import android.view.Surface;
@@ -70,6 +71,10 @@
@Surface.Rotation
int getCurrentRotation();
+ /** Current display state. */
+ @AuthenticateOptions.DisplayState
+ int getDisplayState();
+
/**
* Subscribe to context changes.
*
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
index b63e8e3..dea8030 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
@@ -23,14 +23,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.IBiometricContextListener;
import android.hardware.biometrics.common.OperationContext;
-import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
-import android.os.UserHandle;
import android.util.Slog;
import android.view.Display;
import android.view.WindowManager;
@@ -65,7 +64,6 @@
try {
sInstance = new BiometricContextProvider(context,
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE),
- new AmbientDisplayConfiguration(context),
IStatusBarService.Stub.asInterface(ServiceManager.getServiceOrThrow(
Context.STATUS_BAR_SERVICE)), null /* handler */,
new AuthSessionCoordinator());
@@ -83,8 +81,6 @@
@Nullable
private final Map<Integer, BiometricContextSessionInfo> mSession = new ConcurrentHashMap<>();
-
- private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final AuthSessionCoordinator mAuthSessionCoordinator;
private final WindowManager mWindowManager;
@Nullable private final Handler mHandler;
@@ -93,6 +89,7 @@
private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
private int mFoldState = IBiometricContextListener.FoldState.UNKNOWN;
+ private int mDisplayState = AuthenticateOptions.DISPLAY_STATE_UNKNOWN;
@VisibleForTesting
final BroadcastReceiver mDockStateReceiver = new BroadcastReceiver() {
@Override
@@ -106,11 +103,9 @@
@VisibleForTesting
public BiometricContextProvider(@NonNull Context context,
@NonNull WindowManager windowManager,
- @NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
@NonNull IStatusBarService service, @Nullable Handler handler,
@NonNull AuthSessionCoordinator authSessionCoordinator) {
mWindowManager = windowManager;
- mAmbientDisplayConfiguration = ambientDisplayConfiguration;
mAuthSessionCoordinator = authSessionCoordinator;
mHandler = handler;
@@ -122,11 +117,10 @@
try {
service.setBiometicContextListener(new IBiometricContextListener.Stub() {
@Override
- public void onDozeChanged(boolean isDozing, boolean isAwake) {
- isDozing = isDozing && isAodEnabled();
- final boolean changed = (mIsAod != isDozing) || (mIsAwake != isAwake);
+ public void onDozeChanged(boolean isAod, boolean isAwake) {
+ final boolean changed = (mIsAod != isAod) || (mIsAwake != isAwake);
if (changed) {
- mIsAod = isDozing;
+ mIsAod = isAod;
mIsAwake = isAwake;
notifyChanged();
}
@@ -138,8 +132,12 @@
// no need to notify, not sent to HAL
}
- private boolean isAodEnabled() {
- return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
+ @Override
+ public void onDisplayStateChanged(int displayState) {
+ if (displayState != mDisplayState) {
+ mDisplayState = displayState;
+ notifyChanged();
+ }
}
});
service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() {
@@ -216,6 +214,11 @@
}
@Override
+ public int getDisplayState() {
+ return mDisplayState;
+ }
+
+ @Override
public void subscribe(@NonNull OperationContextExt context,
@NonNull Consumer<OperationContext> consumer) {
mSubscribers.put(context, consumer);
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index 4f2bfd1..aab815c 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -347,31 +347,13 @@
private static boolean isValidHalProgramSelector(
android.hardware.broadcastradio.ProgramSelector sel) {
- if (sel.primaryId.type != IdentifierType.AMFM_FREQUENCY_KHZ
- && sel.primaryId.type != IdentifierType.RDS_PI
- && sel.primaryId.type != IdentifierType.HD_STATION_ID_EXT
- && sel.primaryId.type != IdentifierType.DAB_SID_EXT
- && sel.primaryId.type != IdentifierType.DRMO_SERVICE_ID
- && sel.primaryId.type != IdentifierType.SXM_SERVICE_ID
- && !isVendorIdentifierType(sel.primaryId.type)) {
- return false;
- }
- if (sel.primaryId.type == IdentifierType.DAB_SID_EXT) {
- boolean hasEnsemble = false;
- boolean hasFrequency = false;
- for (int i = 0; i < sel.secondaryIds.length; i++) {
- if (sel.secondaryIds[i].type == IdentifierType.DAB_ENSEMBLE) {
- hasEnsemble = true;
- } else if (sel.secondaryIds[i].type == IdentifierType.DAB_FREQUENCY_KHZ) {
- hasFrequency = true;
- }
- if (hasEnsemble && hasFrequency) {
- return true;
- }
- }
- return false;
- }
- return true;
+ return sel.primaryId.type == IdentifierType.AMFM_FREQUENCY_KHZ
+ || sel.primaryId.type == IdentifierType.RDS_PI
+ || sel.primaryId.type == IdentifierType.HD_STATION_ID_EXT
+ || sel.primaryId.type == IdentifierType.DAB_SID_EXT
+ || sel.primaryId.type == IdentifierType.DRMO_SERVICE_ID
+ || sel.primaryId.type == IdentifierType.SXM_SERVICE_ID
+ || isVendorIdentifierType(sel.primaryId.type);
}
@Nullable
diff --git a/services/core/java/com/android/server/cpu/CpuInfoReader.java b/services/core/java/com/android/server/cpu/CpuInfoReader.java
index ce68edbb..70d7bde 100644
--- a/services/core/java/com/android/server/cpu/CpuInfoReader.java
+++ b/services/core/java/com/android/server/cpu/CpuInfoReader.java
@@ -52,11 +52,6 @@
private static final String POLICY_DIR_PREFIX = "policy";
private static final String RELATED_CPUS_FILE = "related_cpus";
private static final String AFFECTED_CPUS_FILE = "affected_cpus";
- // TODO(b/263154344): Avoid reading from cpuinfo_cur_freq because non-root users don't have
- // read permission for this file. The file permissions are set by the Kernel. Instead, read
- // the current frequency only from scaling_cur_freq.
- private static final String CUR_CPUFREQ_FILE = "cpuinfo_cur_freq";
- private static final String MAX_CPUFREQ_FILE = "cpuinfo_max_freq";
private static final String CUR_SCALING_FREQ_FILE = "scaling_cur_freq";
private static final String MAX_SCALING_FREQ_FILE = "scaling_max_freq";
private static final String TIME_IN_STATE_FILE = "stats/time_in_state";
@@ -207,26 +202,16 @@
Slogf.w(TAG, "Missing dynamic policy info for policy ID %d", policyId);
continue;
}
- long curFreqKHz = CpuInfo.MISSING_FREQUENCY;
- long maxFreqKHz = CpuInfo.MISSING_FREQUENCY;
- if (dynamicPolicyInfo.curCpuFreqPair.cpuFreqKHz != CpuInfo.MISSING_FREQUENCY
- && staticPolicyInfo.maxCpuFreqPair.cpuFreqKHz != CpuInfo.MISSING_FREQUENCY) {
- curFreqKHz = dynamicPolicyInfo.curCpuFreqPair.cpuFreqKHz;
- maxFreqKHz = staticPolicyInfo.maxCpuFreqPair.cpuFreqKHz;
- } else if (dynamicPolicyInfo.curCpuFreqPair.scalingFreqKHz != CpuInfo.MISSING_FREQUENCY
- && staticPolicyInfo.maxCpuFreqPair.scalingFreqKHz
- != CpuInfo.MISSING_FREQUENCY) {
- curFreqKHz = dynamicPolicyInfo.curCpuFreqPair.scalingFreqKHz;
- maxFreqKHz = staticPolicyInfo.maxCpuFreqPair.scalingFreqKHz;
- } else {
+ if (dynamicPolicyInfo.curCpuFreqKHz == CpuInfo.MISSING_FREQUENCY
+ || staticPolicyInfo.maxCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Current and maximum CPU frequency information mismatch/missing for"
+ " policy ID %d", policyId);
continue;
}
- if (curFreqKHz > maxFreqKHz) {
+ if (dynamicPolicyInfo.curCpuFreqKHz > staticPolicyInfo.maxCpuFreqKHz) {
Slogf.w(TAG, "Current CPU frequency (%d) is greater than maximum CPU frequency"
- + " (%d) for policy ID (%d). Skipping CPU frequency policy", curFreqKHz,
- maxFreqKHz, policyId);
+ + " (%d) for policy ID (%d). Skipping CPU frequency policy",
+ dynamicPolicyInfo.curCpuFreqKHz, staticPolicyInfo.maxCpuFreqKHz, policyId);
continue;
}
for (int coreIdx = 0; coreIdx < staticPolicyInfo.relatedCpuCores.size(); coreIdx++) {
@@ -249,7 +234,7 @@
if (dynamicPolicyInfo.affectedCpuCores.indexOf(relatedCpuCore) < 0) {
cpuInfoByCpus.append(relatedCpuCore, new CpuInfo(relatedCpuCore,
cpusetCategories, /* isOnline= */false, CpuInfo.MISSING_FREQUENCY,
- maxFreqKHz, CpuInfo.MISSING_FREQUENCY, usageStats));
+ staticPolicyInfo.maxCpuFreqKHz, CpuInfo.MISSING_FREQUENCY, usageStats));
continue;
}
// If a CPU core is online, it must have the usage stats. When the usage stats is
@@ -260,8 +245,8 @@
continue;
}
CpuInfo cpuInfo = new CpuInfo(relatedCpuCore, cpusetCategories, /* isOnline= */true,
- curFreqKHz, maxFreqKHz, dynamicPolicyInfo.avgTimeInStateCpuFreqKHz,
- usageStats);
+ dynamicPolicyInfo.curCpuFreqKHz, staticPolicyInfo.maxCpuFreqKHz,
+ dynamicPolicyInfo.avgTimeInStateCpuFreqKHz, usageStats);
cpuInfoByCpus.append(relatedCpuCore, cpuInfo);
if (DEBUG) {
Slogf.d(TAG, "Added %s for CPU core %d", cpuInfo, relatedCpuCore);
@@ -438,8 +423,8 @@
for (int i = 0; i < mCpuFreqPolicyDirsById.size(); i++) {
int policyId = mCpuFreqPolicyDirsById.keyAt(i);
File policyDir = mCpuFreqPolicyDirsById.valueAt(i);
- FrequencyPair maxCpuFreqPair = readMaxCpuFrequency(policyDir);
- if (maxCpuFreqPair.isEmpty()) {
+ long maxCpuFreqKHz = readCpuFreqKHz(new File(policyDir, MAX_SCALING_FREQ_FILE));
+ if (maxCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Missing max CPU frequency information at %s",
policyDir.getAbsolutePath());
continue;
@@ -451,7 +436,7 @@
cpuCoresFile.getAbsolutePath());
continue;
}
- StaticPolicyInfo staticPolicyInfo = new StaticPolicyInfo(maxCpuFreqPair,
+ StaticPolicyInfo staticPolicyInfo = new StaticPolicyInfo(maxCpuFreqKHz,
relatedCpuCores);
mStaticPolicyInfoById.append(policyId, staticPolicyInfo);
if (DEBUG) {
@@ -461,18 +446,13 @@
}
}
- private FrequencyPair readMaxCpuFrequency(File policyDir) {
- return new FrequencyPair(readCpuFreqKHz(new File(policyDir, MAX_CPUFREQ_FILE)),
- readCpuFreqKHz(new File(policyDir, MAX_SCALING_FREQ_FILE)));
- }
-
private SparseArray<DynamicPolicyInfo> readDynamicPolicyInfo() {
SparseArray<DynamicPolicyInfo> dynamicPolicyInfoById = new SparseArray<>();
for (int i = 0; i < mCpuFreqPolicyDirsById.size(); i++) {
int policyId = mCpuFreqPolicyDirsById.keyAt(i);
File policyDir = mCpuFreqPolicyDirsById.valueAt(i);
- FrequencyPair curCpuFreqPair = readCurrentCpuFrequency(policyDir);
- if (curCpuFreqPair.isEmpty()) {
+ long curCpuFreqKHz = readCpuFreqKHz(new File(policyDir, CUR_SCALING_FREQ_FILE));
+ if (curCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Missing current frequency information at %s",
policyDir.getAbsolutePath());
continue;
@@ -484,7 +464,7 @@
Slogf.e(TAG, "Failed to read CPU cores from %s", cpuCoresFile.getAbsolutePath());
continue;
}
- DynamicPolicyInfo dynamicPolicyInfo = new DynamicPolicyInfo(curCpuFreqPair,
+ DynamicPolicyInfo dynamicPolicyInfo = new DynamicPolicyInfo(curCpuFreqKHz,
avgTimeInStateCpuFreqKHz, affectedCpuCores);
dynamicPolicyInfoById.append(policyId, dynamicPolicyInfo);
if (DEBUG) {
@@ -495,11 +475,6 @@
return dynamicPolicyInfoById;
}
- private FrequencyPair readCurrentCpuFrequency(File policyDir) {
- return new FrequencyPair(readCpuFreqKHz(new File(policyDir, CUR_CPUFREQ_FILE)),
- readCpuFreqKHz(new File(policyDir, CUR_SCALING_FREQ_FILE)));
- }
-
private long readAvgTimeInStateCpuFrequency(int policyId, File policyDir) {
LongSparseLongArray latestTimeInState = readTimeInState(policyDir);
if (latestTimeInState == null || latestTimeInState.size() == 0) {
@@ -913,58 +888,37 @@
}
}
- private static final class FrequencyPair {
- public final long cpuFreqKHz;
- public final long scalingFreqKHz;
-
- FrequencyPair(long cpuFreqKHz, long scalingFreqKHz) {
- this.cpuFreqKHz = cpuFreqKHz;
- this.scalingFreqKHz = scalingFreqKHz;
- }
-
- boolean isEmpty() {
- return cpuFreqKHz == CpuInfo.MISSING_FREQUENCY
- && scalingFreqKHz == CpuInfo.MISSING_FREQUENCY;
- }
-
- @Override
- public String toString() {
- return "FrequencyPair{cpuFreqKHz = " + cpuFreqKHz + ", scalingFreqKHz = "
- + scalingFreqKHz + '}';
- }
- }
-
private static final class StaticPolicyInfo {
- public final FrequencyPair maxCpuFreqPair;
+ public final long maxCpuFreqKHz;
public final IntArray relatedCpuCores;
- StaticPolicyInfo(FrequencyPair maxCpuFreqPair, IntArray relatedCpuCores) {
- this.maxCpuFreqPair = maxCpuFreqPair;
+ StaticPolicyInfo(long maxCpuFreqKHz, IntArray relatedCpuCores) {
+ this.maxCpuFreqKHz = maxCpuFreqKHz;
this.relatedCpuCores = relatedCpuCores;
}
@Override
public String toString() {
- return "StaticPolicyInfo{maxCpuFreqPair = " + maxCpuFreqPair + ", relatedCpuCores = "
+ return "StaticPolicyInfo{maxCpuFreqKHz = " + maxCpuFreqKHz + ", relatedCpuCores = "
+ relatedCpuCores + '}';
}
}
private static final class DynamicPolicyInfo {
- public final FrequencyPair curCpuFreqPair;
+ public final long curCpuFreqKHz;
public final long avgTimeInStateCpuFreqKHz;
public final IntArray affectedCpuCores;
- DynamicPolicyInfo(FrequencyPair curCpuFreqPair, long avgTimeInStateCpuFreqKHz,
+ DynamicPolicyInfo(long curCpuFreqKHz, long avgTimeInStateCpuFreqKHz,
IntArray affectedCpuCores) {
- this.curCpuFreqPair = curCpuFreqPair;
+ this.curCpuFreqKHz = curCpuFreqKHz;
this.avgTimeInStateCpuFreqKHz = avgTimeInStateCpuFreqKHz;
this.affectedCpuCores = affectedCpuCores;
}
@Override
public String toString() {
- return "DynamicPolicyInfo{curCpuFreqPair = " + curCpuFreqPair
+ return "DynamicPolicyInfo{curCpuFreqKHz = " + curCpuFreqKHz
+ ", avgTimeInStateCpuFreqKHz = " + avgTimeInStateCpuFreqKHz
+ ", affectedCpuCores = " + affectedCpuCores + '}';
}
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 720ea99..af5609a 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -896,7 +896,7 @@
if (mLoggingEnabled) {
Slog.d(TAG, "updateAmbientLux: "
+ ((mFastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
- + "mBrighteningLuxThreshold=" + mAmbientBrighteningThreshold + ", "
+ + "mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold + ", "
+ "mAmbientDarkeningThreshold=" + mAmbientDarkeningThreshold + ", "
+ "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", "
+ "mAmbientLux=" + mAmbientLux);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ea157c8..ea0a4ab 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1514,14 +1514,17 @@
}
}
- // When calling setContentRecordingSession into the WindowManagerService, the WMS
+ // When calling WindowManagerService#setContentRecordingSession, WindowManagerService
// attempts to acquire a lock before executing its main body. Due to this, we need
// to be sure that it isn't called while the DisplayManagerService is also holding
// a lock, to avoid a deadlock scenario.
final ContentRecordingSession session =
virtualDisplayConfig.getContentRecordingSession();
-
- if (displayId != Display.INVALID_DISPLAY && session != null) {
+ // Ensure session details are only set when mirroring (through VirtualDisplay flags or
+ // MediaProjection).
+ final boolean shouldMirror =
+ projection != null || (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0;
+ if (shouldMirror && displayId != Display.INVALID_DISPLAY && session != null) {
// Only attempt to set content recording session if there are details to set and a
// VirtualDisplay has been successfully constructed.
session.setDisplayId(displayId);
@@ -1529,8 +1532,8 @@
// We set the content recording session here on the server side instead of using
// a second AIDL call in MediaProjection. By ensuring that a virtual display has
// been constructed before calling setContentRecordingSession, we avoid a race
- // condition between the DMS & WMS which could lead to the MediaProjection
- // being pre-emptively torn down.
+ // condition between the DisplayManagerService & WindowManagerService which could
+ // lead to the MediaProjection being pre-emptively torn down.
if (!mWindowManagerInternal.setContentRecordingSession(session)) {
// Unable to start mirroring, so tear down projection & release VirtualDisplay.
try {
@@ -2586,9 +2589,7 @@
void setDisplayModeDirectorLoggingEnabled(boolean enabled) {
synchronized (mSyncRoot) {
- if (mDisplayModeDirector != null) {
- mDisplayModeDirector.setLoggingEnabled(enabled);
- }
+ mDisplayModeDirector.setLoggingEnabled(enabled);
}
}
@@ -2849,8 +2850,11 @@
private void dumpInternal(PrintWriter pw) {
pw.println("DISPLAY MANAGER (dumpsys display)");
+ BrightnessTracker brightnessTrackerLocal;
synchronized (mSyncRoot) {
+ brightnessTrackerLocal = mBrightnessTracker;
+
pw.println(" mSafeMode=" + mSafeMode);
pw.println(" mPendingTraversal=" + mPendingTraversal);
pw.println(" mViewports=" + mViewports);
@@ -2923,10 +2927,6 @@
for (int i = 0; i < displayPowerControllerCount; i++) {
mDisplayPowerControllers.valueAt(i).dump(pw);
}
- if (mBrightnessTracker != null) {
- pw.println();
- mBrightnessTracker.dump(pw);
- }
pw.println();
mPersistentDataStore.dump(pw);
@@ -2939,6 +2939,10 @@
mDisplayWindowPolicyControllers.valueAt(i).second.dump(" ", pw);
}
}
+ if (brightnessTrackerLocal != null) {
+ pw.println();
+ brightnessTrackerLocal.dump(pw);
+ }
pw.println();
mDisplayModeDirector.dump(pw);
mBrightnessSynchronizer.dump(pw);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e12cd8c..656882f 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1056,10 +1056,11 @@
}
float userLux = BrightnessMappingStrategy.NO_USER_LUX;
- float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ float userNits = -1;
if (mInteractiveModeBrightnessMapper != null) {
userLux = mInteractiveModeBrightnessMapper.getUserLux();
- userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
+ float userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
+ userNits = mInteractiveModeBrightnessMapper.convertToNits(userBrightness);
}
final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
@@ -1179,6 +1180,13 @@
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.stop();
}
+ float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ if (userNits >= 0) {
+ userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits);
+ if (userBrightness == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
+ userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ }
+ }
mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
this, handler.getLooper(), mSensorManager, mLightSensor,
mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index fbc354e..3e01222 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -893,10 +893,11 @@
}
float userLux = BrightnessMappingStrategy.NO_USER_LUX;
- float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ float userNits = -1;
if (mInteractiveModeBrightnessMapper != null) {
userLux = mInteractiveModeBrightnessMapper.getUserLux();
- userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
+ float userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness();
+ userNits = mInteractiveModeBrightnessMapper.convertToNits(userBrightness);
}
final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
@@ -1016,6 +1017,13 @@
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.stop();
}
+ float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ if (userNits >= 0) {
+ userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits);
+ if (userBrightness == PowerManager.BRIGHTNESS_INVALID_FLOAT) {
+ userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS;
+ }
+ }
mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
this, handler.getLooper(), mSensorManager, mLightSensor,
mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig,
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 8d0689f..79984c9 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -911,7 +911,8 @@
final float newHdrSdrRatio;
if (displayNits != DisplayDeviceConfig.NITS_INVALID
&& sdrNits != DisplayDeviceConfig.NITS_INVALID) {
- newHdrSdrRatio = displayNits / sdrNits;
+ // Ensure the ratio stays >= 1.0f as values below that are nonsensical
+ newHdrSdrRatio = Math.max(1.f, displayNits / sdrNits);
} else {
newHdrSdrRatio = Float.NaN;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 91f58db..35c70fb 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -22,6 +22,7 @@
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
import android.hardware.tv.cec.V1_0.Result;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.media.AudioManager;
@@ -827,7 +828,7 @@
KeyEvent.FLAG_FROM_SYSTEM,
InputDevice.SOURCE_HDMI,
null);
- InputManager.getInstance()
+ InputManagerGlobal.getInstance()
.injectInputEvent(keyEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
keyEvent.recycle();
}
diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java
index 773dc68..5132591 100644
--- a/services/core/java/com/android/server/input/InputShellCommand.java
+++ b/services/core/java/com/android/server/input/InputShellCommand.java
@@ -42,6 +42,7 @@
import static java.util.Collections.unmodifiableMap;
import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.util.ArrayMap;
@@ -109,7 +110,7 @@
}
private void injectKeyEvent(KeyEvent event) {
- InputManager.getInstance().injectInputEvent(event,
+ InputManagerGlobal.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
@@ -178,7 +179,7 @@
pointerProperties, pointerCoords, DEFAULT_META_STATE, DEFAULT_BUTTON_STATE,
DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, getInputDeviceId(inputSource),
DEFAULT_EDGE_FLAGS, inputSource, displayId, DEFAULT_FLAGS);
- InputManager.getInstance().injectInputEvent(event,
+ InputManagerGlobal.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
@@ -530,7 +531,7 @@
}
private void injectKeyEventAsync(KeyEvent event) {
- InputManager.getInstance().injectInputEvent(event,
+ InputManagerGlobal.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index eb4dba6..502855d 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -25,6 +25,7 @@
import android.annotation.RequiresPermission;
import android.annotation.UiThread;
import android.hardware.input.InputManager;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.text.TextUtils;
@@ -55,17 +56,20 @@
public static final String TAG = HandwritingModeController.class.getSimpleName();
// TODO(b/210039666): flip the flag.
static final boolean DEBUG = true;
+ // Use getHandwritingBufferSize() and not this value directly.
private static final int EVENT_BUFFER_SIZE = 100;
// A longer event buffer used for handwriting delegation
// TODO(b/210039666): make this device touch sampling rate dependent.
- private static final int LONG_EVENT_BUFFER = EVENT_BUFFER_SIZE * 20;
+ // Use getHandwritingBufferSize() and not this value directly.
+ private static final int LONG_EVENT_BUFFER_SIZE = EVENT_BUFFER_SIZE * 20;
+ private static final long HANDWRITING_DELEGATION_IDLE_TIMEOUT_MS = 3000;
// This must be the looper for the UiThread.
private final Looper mLooper;
private final InputManagerInternal mInputManagerInternal;
private final WindowManagerInternal mWindowManagerInternal;
- private List<MotionEvent> mHandwritingBuffer;
+ private ArrayList<MotionEvent> mHandwritingBuffer;
private InputEventReceiver mHandwritingEventReceiver;
private Runnable mInkWindowInitRunnable;
private boolean mRecordingGesture;
@@ -73,6 +77,8 @@
// when set, package names are used for handwriting delegation.
private @Nullable String mDelegatePackageName;
private @Nullable String mDelegatorPackageName;
+ private Runnable mDelegationIdleTimeoutRunnable;
+ private Handler mDelegationIdleTimeoutHandler;
private HandwritingEventReceiverSurface mHandwritingSurface;
@@ -110,7 +116,7 @@
mCurrentDisplayId = displayId;
if (mHandwritingBuffer == null) {
- mHandwritingBuffer = new ArrayList<>(EVENT_BUFFER_SIZE);
+ mHandwritingBuffer = new ArrayList<>(getHandwritingBufferSize());
}
if (DEBUG) Slog.d(TAG, "Initializing handwriting spy monitor for display: " + displayId);
@@ -159,8 +165,8 @@
@NonNull String delegatePackageName, @NonNull String delegatorPackageName) {
mDelegatePackageName = delegatePackageName;
mDelegatorPackageName = delegatorPackageName;
- ((ArrayList) mHandwritingBuffer).ensureCapacity(LONG_EVENT_BUFFER);
- // TODO(b/210039666): cancel delegation after a timeout or next input method client binding.
+ mHandwritingBuffer.ensureCapacity(getHandwritingBufferSize());
+ scheduleHandwritingDelegationTimeout();
}
@Nullable String getDelegatePackageName() {
@@ -171,6 +177,32 @@
return mDelegatorPackageName;
}
+ private void scheduleHandwritingDelegationTimeout() {
+ if (mDelegationIdleTimeoutHandler == null) {
+ mDelegationIdleTimeoutHandler = new Handler(mLooper);
+ } else {
+ mDelegationIdleTimeoutHandler.removeCallbacks(mDelegationIdleTimeoutRunnable);
+ }
+ mDelegationIdleTimeoutRunnable = () -> {
+ Slog.d(TAG, "Stylus handwriting delegation idle timed-out.");
+ clearPendingHandwritingDelegation();
+ if (mHandwritingBuffer != null) {
+ mHandwritingBuffer.forEach(MotionEvent::recycle);
+ mHandwritingBuffer.clear();
+ mHandwritingBuffer.trimToSize();
+ mHandwritingBuffer.ensureCapacity(getHandwritingBufferSize());
+ }
+ };
+ mDelegationIdleTimeoutHandler.postDelayed(
+ mDelegationIdleTimeoutRunnable, HANDWRITING_DELEGATION_IDLE_TIMEOUT_MS);
+ }
+
+ private int getHandwritingBufferSize() {
+ if (mDelegatePackageName != null && mDelegatorPackageName != null) {
+ return LONG_EVENT_BUFFER_SIZE;
+ }
+ return EVENT_BUFFER_SIZE;
+ }
/**
* Clear any pending handwriting delegation info.
*/
@@ -178,6 +210,11 @@
if (DEBUG) {
Slog.d(TAG, "clearPendingHandwritingDelegation");
}
+ if (mDelegationIdleTimeoutHandler != null) {
+ mDelegationIdleTimeoutHandler.removeCallbacks(mDelegationIdleTimeoutRunnable);
+ mDelegationIdleTimeoutHandler = null;
+ }
+ mDelegationIdleTimeoutRunnable = null;
mDelegatorPackageName = null;
mDelegatePackageName = null;
}
@@ -322,7 +359,7 @@
return;
}
- if (mHandwritingBuffer.size() >= EVENT_BUFFER_SIZE) {
+ if (mHandwritingBuffer.size() >= getHandwritingBufferSize()) {
if (DEBUG) {
Slog.w(TAG, "Current gesture exceeds the buffer capacity."
+ " The rest of the gesture will not be recorded.");
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 991930f..ec03d9d 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -65,6 +65,7 @@
import com.android.server.integrity.engine.RuleEvaluationEngine;
import com.android.server.integrity.model.IntegrityCheckResult;
import com.android.server.integrity.model.RuleMetadata;
+import com.android.server.pm.PackageManagerServiceUtils;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
@@ -383,7 +384,7 @@
private String getInstallerPackageName(Intent intent) {
String installer =
intent.getStringExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE);
- if (installer == null) {
+ if (PackageManagerServiceUtils.isInstalledByAdb(installer)) {
return ADB_INSTALLER;
}
int installerUid = intent.getIntExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, -1);
diff --git a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
index a081dff..5ef89ad 100644
--- a/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
+++ b/services/core/java/com/android/server/location/gnss/GnssConfiguration.java
@@ -54,7 +54,9 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
+ private static final String DEBUG_PROPERTIES_SYSTEM_FILE = "/etc/gps_debug.conf";
+
+ private static final String DEBUG_PROPERTIES_VENDOR_FILE = "/vendor/etc/gps_debug.conf";
// config.xml properties
private static final String CONFIG_SUPL_HOST = "SUPL_HOST";
@@ -285,7 +287,8 @@
/*
* Overlay carrier properties from a debug configuration file.
*/
- loadPropertiesFromGpsDebugConfig(mProperties);
+ loadPropertiesFromGpsDebugConfig(mProperties, DEBUG_PROPERTIES_VENDOR_FILE);
+ loadPropertiesFromGpsDebugConfig(mProperties, DEBUG_PROPERTIES_SYSTEM_FILE);
mEsExtensionSec = getRangeCheckedConfigEsExtensionSec();
logConfigurations();
@@ -392,9 +395,9 @@
}
}
- private void loadPropertiesFromGpsDebugConfig(Properties properties) {
+ private void loadPropertiesFromGpsDebugConfig(Properties properties, String filePath) {
try {
- File file = new File(DEBUG_PROPERTIES_FILE);
+ File file = new File(filePath);
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
@@ -403,7 +406,7 @@
IoUtils.closeQuietly(stream);
}
} catch (IOException e) {
- if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + DEBUG_PROPERTIES_FILE);
+ if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + filePath);
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index 1aee345..f107d0b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -106,6 +106,14 @@
case COMMAND_HELP:
onHelp();
return 0;
+ case COMMAND_GET_DISABLED:
+ runGetDisabled();
+ return 0;
+ case COMMAND_SET_DISABLED:
+ // Note: if the user has an LSKF, then this has no immediate effect but instead
+ // just ensures the lockscreen will be disabled later when the LSKF is cleared.
+ runSetDisabled();
+ return 0;
}
if (!checkCredential()) {
return -1;
@@ -124,15 +132,9 @@
case COMMAND_CLEAR:
success = runClear();
break;
- case COMMAND_SET_DISABLED:
- runSetDisabled();
- break;
case COMMAND_VERIFY:
runVerify();
break;
- case COMMAND_GET_DISABLED:
- runGetDisabled();
- break;
default:
getErrPrintWriter().println("Unknown command: " + cmd);
break;
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
index fa53a607..0e5e55c 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
@@ -122,14 +123,14 @@
}
private static int getDbVersion(Context context) {
- // TODO(b/254335492): Check flag
+ // TODO(b/254335492): Update to version 7 and clean up code.
return DATABASE_VERSION;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_KEYS_ENTRY);
- if (db.getVersion() == 6) {
+ if (db.getVersion() == 6) { // always false
db.execSQL(SQL_CREATE_USER_METADATA_ENTRY);
} else {
db.execSQL(SQL_CREATE_USER_METADATA_ENTRY_FOR_V7);
@@ -147,37 +148,47 @@
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion < 2) {
+ try {
+ if (oldVersion < 2) {
+ dropAllKnownTables(db); // Wipe database.
+ onCreate(db);
+ return;
+ }
+
+ if (oldVersion < 3 && newVersion >= 3) {
+ upgradeDbForVersion3(db);
+ oldVersion = 3;
+ }
+
+ if (oldVersion < 4 && newVersion >= 4) {
+ upgradeDbForVersion4(db);
+ oldVersion = 4;
+ }
+
+ if (oldVersion < 5 && newVersion >= 5) {
+ upgradeDbForVersion5(db);
+ oldVersion = 5;
+ }
+
+ if (oldVersion < 6 && newVersion >= 6) {
+ upgradeDbForVersion6(db);
+ oldVersion = 6;
+ }
+
+ if (oldVersion < 7 && newVersion >= 7) {
+ try {
+ upgradeDbForVersion7(db);
+ } catch (SQLiteException e) {
+ Log.w(TAG, "Column was added without version update - ignore error", e);
+ }
+ oldVersion = 7;
+ }
+ } catch (SQLiteException e) {
+ Log.e(TAG, "Recreating recoverablekeystore after unexpected upgrade error.", e);
dropAllKnownTables(db); // Wipe database.
onCreate(db);
return;
}
-
- if (oldVersion < 3 && newVersion >= 3) {
- upgradeDbForVersion3(db);
- oldVersion = 3;
- }
-
- if (oldVersion < 4 && newVersion >= 4) {
- upgradeDbForVersion4(db);
- oldVersion = 4;
- }
-
- if (oldVersion < 5 && newVersion >= 5) {
- upgradeDbForVersion5(db);
- oldVersion = 5;
- }
-
- if (oldVersion < 6 && newVersion >= 6) {
- upgradeDbForVersion6(db);
- oldVersion = 6;
- }
-
- if (oldVersion < 7 && newVersion >= 7) {
- upgradeDbForVersion7(db);
- oldVersion = 7;
- }
-
if (oldVersion != newVersion) {
Log.e(TAG, "Failed to update recoverablekeystore database to the most recent version");
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 2774462..8277041 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1258,17 +1258,18 @@
.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
.writeByteArray(config.toZenPolicy().toProto());
events.add(data.build());
- if (config.manualRule != null && config.manualRule.enabler != null) {
- ruleToProtoLocked(user, config.manualRule, events);
+ if (config.manualRule != null) {
+ ruleToProtoLocked(user, config.manualRule, true, events);
}
for (ZenRule rule : config.automaticRules.values()) {
- ruleToProtoLocked(user, rule, events);
+ ruleToProtoLocked(user, rule, false, events);
}
}
}
}
- private void ruleToProtoLocked(int user, ZenRule rule, List<StatsEvent> events) {
+ private void ruleToProtoLocked(int user, ZenRule rule, boolean isManualRule,
+ List<StatsEvent> events) {
// Make the ID safe.
String id = rule.id == null ? "" : rule.id;
if (!ZenModeConfig.DEFAULT_RULE_IDS.contains(id)) {
@@ -1279,6 +1280,9 @@
String pkg = rule.getPkg() == null ? "" : rule.getPkg();
if (rule.enabler != null) {
pkg = rule.enabler;
+ }
+
+ if (isManualRule) {
id = ZenModeConfig.MANUAL_RULE_ID;
}
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index 9e93fe0..2e1c72e 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -47,7 +47,6 @@
import android.os.SystemClock;
import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalStorage;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
@@ -424,7 +423,7 @@
@Nullable Certificate[] trustedInstallers,
Map<Integer, ApkChecksum> checksums,
@NonNull Injector injector) {
- if (TextUtils.isEmpty(installerPackageName)) {
+ if (PackageManagerServiceUtils.isInstalledByAdb(installerPackageName)) {
return;
}
if (trustedInstallers != null && trustedInstallers.length == 0) {
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index 2e86df8..f95f7bc 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -18,7 +18,6 @@
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static com.android.server.pm.DexOptHelper.useArtService;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerServiceUtils.getPackageManagerLocal;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
@@ -245,7 +244,7 @@
}
}
- if (!useArtService()) { // ART Service handles this on demand instead.
+ if (!DexOptHelper.useArtService()) { // ART Service handles this on demand instead.
// Prepare the application profiles only for upgrades and
// first boot (so that we don't repeat the same operation at
// each boot).
@@ -591,7 +590,7 @@
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
- if (useArtService()) {
+ if (DexOptHelper.useArtService()) {
destroyAppProfilesWithArtService(pkg);
} else {
try {
@@ -637,7 +636,7 @@
}
private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
- if (useArtService()) {
+ if (DexOptHelper.useArtService()) {
destroyAppProfilesWithArtService(pkg);
} else {
try {
@@ -651,6 +650,15 @@
}
private void destroyAppProfilesWithArtService(AndroidPackage pkg) {
+ if (!DexOptHelper.artManagerLocalIsInitialized()) {
+ // This function may get called while PackageManagerService is constructed (via e.g.
+ // InitAppsHelper.initSystemApps), and ART Service hasn't yet been started then (it
+ // requires a registered PackageManagerLocal instance). We can skip clearing any stale
+ // app profiles in this case, because ART Service and the runtime will ignore stale or
+ // otherwise invalid ref and cur profiles.
+ return;
+ }
+
try (PackageManagerLocal.FilteredSnapshot snapshot =
getPackageManagerLocal().withFilteredSnapshot()) {
try {
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index 8d40adf..0bb05aa 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -248,7 +248,7 @@
// ADB sets installerPackageName to null, this creates a loophole to bypass BIC which will be
// addressed with b/265203007
private boolean installedByAdb(String initiatingPackageName) {
- return initiatingPackageName == null;
+ return PackageManagerServiceUtils.isInstalledByAdb(initiatingPackageName);
}
private boolean wasForegroundInstallation(String installerPackageName,
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index a9d4115..064be7c 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -99,6 +99,8 @@
public final class DexOptHelper {
private static final long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000;
+ private static boolean sArtManagerLocalIsInitialized = false;
+
private final PackageManagerService mPm;
// Start time for the boot dexopt in performPackageDexOptUpgradeIfNeeded when ART Service is
@@ -1035,6 +1037,7 @@
artManager.addDexoptDoneCallback(false /* onlyIncludeUpdates */, Runnable::run,
pm.getDexOptHelper().new DexoptDoneHandler());
LocalManagerRegistry.addManager(ArtManagerLocal.class, artManager);
+ sArtManagerLocalIsInitialized = true;
// Schedule the background job when boot is complete. This decouples us from when
// JobSchedulerService is initialized.
@@ -1048,6 +1051,15 @@
}
/**
+ * Returns true if an {@link ArtManagerLocal} instance has been created.
+ *
+ * Avoid this function if at all possible, because it may hide initialization order problems.
+ */
+ public static boolean artManagerLocalIsInitialized() {
+ return sArtManagerLocalIsInitialized;
+ }
+
+ /**
* Returns the registered {@link ArtManagerLocal} instance, or else throws an unchecked error.
*/
public static @NonNull ArtManagerLocal getArtManagerLocal() {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index cd1ae74..5f424ed 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -90,6 +90,7 @@
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
+import static com.android.server.pm.PackageManagerServiceUtils.isInstalledByAdb;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
import static com.android.server.pm.SharedUidMigration.BEST_EFFORT;
@@ -333,7 +334,7 @@
if (installSource != null) {
// If this is part of a standard install, set the initiating package name, else rely on
// previous device state.
- if (installSource.mInitiatingPackageName != null) {
+ if (!isInstalledByAdb(installSource.mInitiatingPackageName)) {
final PackageSetting ips = mPm.mSettings.getPackageLPr(
installSource.mInitiatingPackageName);
if (ips != null) {
@@ -4276,10 +4277,14 @@
deletePackageHelper.deletePackageLIF(parsedPackage.getPackageName(), null, true,
mPm.mUserManager.getUserIds(), 0, null, false);
}
- } else if (newPkgVersionGreater) {
+ } else if (newPkgVersionGreater || newSharedUserSetting) {
// The application on /system is newer than the application on /data.
// Simply remove the application on /data [keeping application data]
// and replace it with the version on /system.
+ // Also, if the sharedUserSetting of the application on /system is different
+ // from the sharedUserSetting on data, we should trust the sharedUserSetting
+ // on /system, even if the application version on /system is smaller than
+ // the version on /data.
logCriticalInfo(Log.WARN,
"System package enabled;"
+ " name: " + pkgSetting.getPackageName()
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 0d417e4..68c8abf 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -821,8 +821,10 @@
* Creates an oat dir for given package and instruction set.
*/
public void createOatDir(String packageName, String oatDir, String dexInstructionSet)
- throws InstallerException, LegacyDexoptDisabledException {
- checkLegacyDexoptDisabled();
+ throws InstallerException {
+ // This method should be allowed even if ART Service is enabled, because it's used for
+ // creating oat dirs before creating hard links for partial installation.
+ // TODO(b/274658735): Add an ART Service API to support hard linking.
if (!checkBeforeRemote()) return;
try {
mInstalld.createOatDir(packageName, oatDir, dexInstructionSet);
@@ -1177,7 +1179,7 @@
// TODO(b/260124949): Remove the legacy dexopt code paths, i.e. this exception and all code
// that may throw it.
public LegacyDexoptDisabledException() {
- super("Invalid call to legacy dexopt installd method while ART Service is in use.");
+ super("Invalid call to legacy dexopt method while ART Service is in use.");
}
}
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 7f7a234..83d2f6a 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -132,14 +132,15 @@
// Not found or complete.
break;
}
- if (!streaming && state.timeoutExtended()) {
+
+ final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
+ if (!streaming && state.timeoutExtended(response.callerUid)) {
// Timeout extended.
break;
}
- final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
- VerificationUtils.processVerificationResponse(verificationId, state, response,
- "Verification timed out", mPm);
+ VerificationUtils.processVerificationResponseOnTimeout(verificationId, state,
+ response, mPm);
break;
}
@@ -195,8 +196,7 @@
}
final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
- VerificationUtils.processVerificationResponse(verificationId, state, response,
- "Install not allowed", mPm);
+ VerificationUtils.processVerificationResponse(verificationId, state, response, mPm);
break;
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index adc0b0b..69e92e0 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -19,6 +19,8 @@
import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_DELETED_BY_DO;
import static android.os.Process.INVALID_UID;
+import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;
+
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -679,7 +681,7 @@
params.installFlags |= PackageManager.INSTALL_FROM_ADB;
// adb installs can override the installingPackageName, but not the
// initiatingPackageName
- installerPackageName = null;
+ installerPackageName = SHELL_PACKAGE_NAME;
} else {
if (callingUid != Process.SYSTEM_UID) {
// The supplied installerPackageName must always belong to the calling app.
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 03e0d36..ea6383e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -49,9 +49,9 @@
import static com.android.internal.util.XmlUtils.writeByteArrayAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static com.android.internal.util.XmlUtils.writeUriAttribute;
-import static com.android.server.pm.DexOptHelper.useArtService;
import static com.android.server.pm.PackageInstallerService.prepareStageDir;
import static com.android.server.pm.PackageManagerService.APP_METADATA_FILE_NAME;
+import static com.android.server.pm.PackageManagerServiceUtils.isInstalledByAdb;
import android.Manifest;
import android.annotation.AnyThread;
@@ -173,7 +173,6 @@
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException;
-import com.android.server.pm.Installer.LegacyDexoptDisabledException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -1397,9 +1396,10 @@
return;
}
+ final String initiatingPackageName = getInstallSource().mInitiatingPackageName;
final String installerPackageName;
- if (!TextUtils.isEmpty(getInstallSource().mInitiatingPackageName)) {
- installerPackageName = getInstallSource().mInitiatingPackageName;
+ if (!isInstalledByAdb(initiatingPackageName)) {
+ installerPackageName = initiatingPackageName;
} else {
installerPackageName = getInstallSource().mInstallerPackageName;
}
@@ -2560,15 +2560,9 @@
}
if (isLinkPossible(fromFiles, toDir)) {
- if (!useArtService()) { // ART Service creates oat dirs on demand instead.
- if (!mResolvedInstructionSets.isEmpty()) {
- final File oatDir = new File(toDir, "oat");
- try {
- createOatDirs(tempPackageName, mResolvedInstructionSets, oatDir);
- } catch (LegacyDexoptDisabledException e) {
- throw new RuntimeException(e);
- }
- }
+ if (!mResolvedInstructionSets.isEmpty()) {
+ final File oatDir = new File(toDir, "oat");
+ createOatDirs(tempPackageName, mResolvedInstructionSets, oatDir);
}
// pre-create lib dirs for linking if necessary
if (!mResolvedNativeLibPaths.isEmpty()) {
@@ -3829,7 +3823,7 @@
}
private void createOatDirs(String packageName, List<String> instructionSets, File fromDir)
- throws PackageManagerException, LegacyDexoptDisabledException {
+ throws PackageManagerException {
for (String instructionSet : instructionSets) {
try {
mInstaller.createOatDir(packageName, fromDir.getAbsolutePath(), instructionSet);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6bc8760..d630ff4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -43,6 +43,7 @@
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
+import static com.android.server.pm.PackageManagerServiceUtils.isInstalledByAdb;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import android.Manifest;
@@ -351,6 +352,8 @@
static final boolean DEBUG_ABI_SELECTION = false;
public static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
+ static final String SHELL_PACKAGE_NAME = "com.android.shell";
+
static final boolean HIDE_EPHEMERAL_APIS = false;
static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";
@@ -1330,10 +1333,11 @@
final InstallSourceInfo installSourceInfo = snapshot.getInstallSourceInfo(packageName,
userId);
+ final String initiatingPackageName = installSourceInfo.getInitiatingPackageName();
final String installerPackageName;
if (installSourceInfo != null) {
- if (!TextUtils.isEmpty(installSourceInfo.getInitiatingPackageName())) {
- installerPackageName = installSourceInfo.getInitiatingPackageName();
+ if (!isInstalledByAdb(initiatingPackageName)) {
+ installerPackageName = initiatingPackageName;
} else {
installerPackageName = installSourceInfo.getInstallingPackageName();
}
@@ -4885,14 +4889,11 @@
mHandler.post(() -> {
final int id = verificationId >= 0 ? verificationId : -verificationId;
final PackageVerificationState state = mPendingVerification.get(id);
- if (state == null || state.timeoutExtended() || !state.checkRequiredVerifierUid(
- callingUid)) {
- // Only allow calls from required verifiers.
+ if (state == null || !state.extendTimeout(callingUid)) {
+ // Invalid uid or already extended.
return;
}
- state.extendTimeout();
-
final PackageVerificationResponse response = new PackageVerificationResponse(
verificationCodeAtTimeout, callingUid);
@@ -5561,32 +5562,18 @@
public void registerDexModule(String packageName, String dexModulePath,
boolean isSharedModule,
IDexModuleRegisterCallback callback) {
- if (useArtService()) {
- // ART Service currently doesn't support this explicit dexopting and instead relies
- // on background dexopt for secondary dex files. This API is problematic since it
- // doesn't provide the correct classloader context.
- Slog.i(TAG,
- "Ignored unsupported registerDexModule call for " + dexModulePath + " in "
- + packageName);
- return;
- }
-
- int userId = UserHandle.getCallingUserId();
- ApplicationInfo ai = snapshot().getApplicationInfo(packageName, /*flags*/ 0, userId);
- DexManager.RegisterDexModuleResult result;
- if (ai == null) {
- Slog.w(PackageManagerService.TAG,
- "Registering a dex module for a package that does not exist for the" +
- " calling user. package=" + packageName + ", user=" + userId);
- result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
- } else {
- try {
- result = mDexManager.registerDexModule(
- ai, dexModulePath, isSharedModule, userId);
- } catch (LegacyDexoptDisabledException e) {
- throw new RuntimeException(e);
- }
- }
+ // ART Service doesn't support this explicit dexopting and instead relies on background
+ // dexopt for secondary dex files. For compat parity between ART Service and the legacy
+ // code it's disabled for both.
+ //
+ // Also, this API is problematic anyway since it doesn't provide the correct classloader
+ // context, so it is hard to produce dexopt artifacts that the runtime can load
+ // successfully.
+ Slog.i(TAG,
+ "Ignored unsupported registerDexModule call for " + dexModulePath + " in "
+ + packageName);
+ DexManager.RegisterDexModuleResult result = new DexManager.RegisterDexModuleResult(
+ false, "registerDexModule call not supported since Android U");
if (callback != null) {
mHandler.post(() -> {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 3f9a0bc..77e4688 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -32,6 +32,7 @@
import static com.android.server.pm.PackageManagerService.DEBUG_PREFERRED;
import static com.android.server.pm.PackageManagerService.RANDOM_CODEPATH_PREFIX;
import static com.android.server.pm.PackageManagerService.RANDOM_DIR_PREFIX;
+import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.STUB_SUFFIX;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -1516,4 +1517,11 @@
}
}
}
+
+ /**
+ * Check if package name is com.android.shell or is null.
+ */
+ public static boolean isInstalledByAdb(String initiatingPackageName) {
+ return initiatingPackageName == null || SHELL_PACKAGE_NAME.equals(initiatingPackageName);
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java
index 929bc1e..0b6ccc4 100644
--- a/services/core/java/com/android/server/pm/PackageVerificationState.java
+++ b/services/core/java/com/android/server/pm/PackageVerificationState.java
@@ -33,6 +33,8 @@
private final SparseBooleanArray mRequiredVerifierUids;
private final SparseBooleanArray mUnrespondedRequiredVerifierUids;
+ private final SparseBooleanArray mExtendedTimeoutUids;
+
private boolean mSufficientVerificationComplete;
private boolean mSufficientVerificationPassed;
@@ -41,8 +43,6 @@
private boolean mRequiredVerificationPassed;
- private boolean mExtendedTimeout;
-
private boolean mIntegrityVerificationComplete;
/**
@@ -54,9 +54,9 @@
mSufficientVerifierUids = new SparseBooleanArray();
mRequiredVerifierUids = new SparseBooleanArray();
mUnrespondedRequiredVerifierUids = new SparseBooleanArray();
+ mExtendedTimeoutUids = new SparseBooleanArray();
mRequiredVerificationComplete = false;
mRequiredVerificationPassed = true;
- mExtendedTimeout = false;
}
VerifyingSession getVerifyingSession() {
@@ -88,14 +88,27 @@
return mSufficientVerifierUids.get(uid, false);
}
+ void setVerifierResponseOnTimeout(int uid, int code) {
+ if (!checkRequiredVerifierUid(uid)) {
+ return;
+ }
+
+ // Timeout, not waiting for the sufficient verifiers anymore.
+ mSufficientVerifierUids.clear();
+
+ // Only if unresponded.
+ if (mUnrespondedRequiredVerifierUids.get(uid, false)) {
+ setVerifierResponse(uid, code);
+ }
+ }
+
/**
* Should be called when a verification is received from an agent so the state of the package
* verification can be tracked.
*
* @param uid user ID of the verifying agent
- * @return {@code true} if the verifying agent actually exists in our list
*/
- boolean setVerifierResponse(int uid, int code) {
+ void setVerifierResponse(int uid, int code) {
if (mRequiredVerifierUids.get(uid)) {
switch (code) {
case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT:
@@ -109,13 +122,19 @@
break;
default:
mRequiredVerificationPassed = false;
+ // Required verifier rejected, no need to wait for the rest.
+ mUnrespondedRequiredVerifierUids.clear();
+ mSufficientVerifierUids.clear();
+ mExtendedTimeoutUids.clear();
}
+ // Responded, no need to extend timeout.
+ mExtendedTimeoutUids.delete(uid);
+
mUnrespondedRequiredVerifierUids.delete(uid);
if (mUnrespondedRequiredVerifierUids.size() == 0) {
mRequiredVerificationComplete = true;
}
- return true;
} else if (mSufficientVerifierUids.get(uid)) {
if (code == PackageManager.VERIFICATION_ALLOW) {
mSufficientVerificationPassed = true;
@@ -126,11 +145,7 @@
if (mSufficientVerifierUids.size() == 0) {
mSufficientVerificationComplete = true;
}
-
- return true;
}
-
- return false;
}
/**
@@ -181,10 +196,12 @@
}
/** Extend the timeout for this Package to be verified. */
- void extendTimeout() {
- if (!mExtendedTimeout) {
- mExtendedTimeout = true;
+ boolean extendTimeout(int uid) {
+ if (!checkRequiredVerifierUid(uid) || timeoutExtended(uid)) {
+ return false;
}
+ mExtendedTimeoutUids.append(uid, true);
+ return true;
}
/**
@@ -192,8 +209,8 @@
*
* @return {@code true} if a timeout was already extended.
*/
- boolean timeoutExtended() {
- return mExtendedTimeout;
+ boolean timeoutExtended(int uid) {
+ return mExtendedTimeoutUids.get(uid, false);
}
void setIntegrityVerificationResult(int code) {
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 18eebe4..b4b8cb2 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -619,10 +619,10 @@
final Bundle extras = new Bundle(3);
extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
+ final int flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND;
handler.post(() -> mBroadcastHelper.sendPackageBroadcast(intent, null /* pkg */,
- extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
- null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
- null /* broadcastAllowList */,
+ extras, flags, null /* targetPkg */, null /* finishedReceiver */,
+ new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */,
(callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList(
mPm.snapshotComputer(), callingUid, intentExtras),
null /* bOptions */));
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 721ad88..194f237 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -506,15 +506,14 @@
*
* <p>If the user is a profile and is running, it's assigned to its parent display.
*/
- // TODO(b/272366483) rename this method to avoid confusion with getDisplaysAssignedTOUser().
- public abstract int getDisplayAssignedToUser(@UserIdInt int userId);
+ public abstract int getMainDisplayAssignedToUser(@UserIdInt int userId);
/**
* Returns all display ids assigned to the user including {@link
* #assignUserToExtraDisplay(int, int) extra displays}, or {@code null} if there is no display
* assigned to the specified user.
*
- * <p>Note that this method is different from {@link #getDisplayAssignedToUser(int)}, which
+ * <p>Note that this method is different from {@link #getMainDisplayAssignedToUser(int)}, which
* returns a main display only.
*/
public abstract @Nullable int[] getDisplaysAssignedToUser(@UserIdInt int userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 7414640..a36e9f9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1275,7 +1275,7 @@
intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers(
intent, parentHandle, /* requiresPermission= */ true);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcastAsUser(intent, parentHandle);
}
@@ -1996,10 +1996,10 @@
}
@Override
- public int getDisplayIdAssignedToUser() {
+ public int getMainDisplayIdAssignedToUser() {
// Not checking for any permission as it returns info about calling user
int userId = UserHandle.getUserId(Binder.getCallingUid());
- int displayId = mUserVisibilityMediator.getDisplayAssignedToUser(userId);
+ int displayId = mUserVisibilityMediator.getMainDisplayAssignedToUser(userId);
return displayId;
}
@@ -7189,8 +7189,8 @@
}
@Override
- public int getDisplayAssignedToUser(@UserIdInt int userId) {
- return mUserVisibilityMediator.getDisplayAssignedToUser(userId);
+ public int getMainDisplayAssignedToUser(@UserIdInt int userId) {
+ return mUserVisibilityMediator.getMainDisplayAssignedToUser(userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
index 3710af6..cf82536 100644
--- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java
+++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
@@ -774,9 +774,9 @@
}
/**
- * See {@link UserManagerInternal#getDisplayAssignedToUser(int)}.
+ * See {@link UserManagerInternal#getMainDisplayAssignedToUser(int)}.
*/
- public int getDisplayAssignedToUser(@UserIdInt int userId) {
+ public int getMainDisplayAssignedToUser(@UserIdInt int userId) {
if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) {
if (mVisibleBackgroundUserOnDefaultDisplayEnabled) {
// When device supports visible bg users on default display, the default display is
@@ -787,8 +787,8 @@
}
if (userStartedOnDefaultDisplay != USER_NULL) {
if (DBG) {
- Slogf.d(TAG, "getDisplayAssignedToUser(%d): returning INVALID_DISPLAY for "
- + "current user user %d was started on DEFAULT_DISPLAY",
+ Slogf.d(TAG, "getMainDisplayAssignedToUser(%d): returning INVALID_DISPLAY "
+ + "for current user user %d was started on DEFAULT_DISPLAY",
userId, userStartedOnDefaultDisplay);
}
return INVALID_DISPLAY;
@@ -809,7 +809,7 @@
/** See {@link UserManagerInternal#getDisplaysAssignedToUser(int)}. */
@Nullable
public int[] getDisplaysAssignedToUser(@UserIdInt int userId) {
- int mainDisplayId = getDisplayAssignedToUser(userId);
+ int mainDisplayId = getMainDisplayAssignedToUser(userId);
if (mainDisplayId == INVALID_DISPLAY) {
// The user will not have any extra displays if they have no main display.
// Return null if no display is assigned to the user.
diff --git a/services/core/java/com/android/server/pm/VerificationUtils.java b/services/core/java/com/android/server/pm/VerificationUtils.java
index 30f2132..f061018 100644
--- a/services/core/java/com/android/server/pm/VerificationUtils.java
+++ b/services/core/java/com/android/server/pm/VerificationUtils.java
@@ -18,6 +18,7 @@
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.server.pm.PackageManagerService.PACKAGE_MIME_TYPE;
import static com.android.server.pm.PackageManagerService.TAG;
@@ -32,6 +33,8 @@
import android.provider.Settings;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
final class VerificationUtils {
/**
* The default maximum time to wait for the verification agent to return in
@@ -97,39 +100,63 @@
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
}
+ @VisibleForTesting(visibility = PACKAGE)
+ static void processVerificationResponseOnTimeout(int verificationId,
+ PackageVerificationState state, PackageVerificationResponse response,
+ PackageManagerService pms) {
+ state.setVerifierResponseOnTimeout(response.callerUid, response.code);
+ processVerificationResponse(verificationId, state, response.code, "Verification timed out",
+ pms);
+ }
+
+ @VisibleForTesting(visibility = PACKAGE)
static void processVerificationResponse(int verificationId, PackageVerificationState state,
- PackageVerificationResponse response, String failureReason, PackageManagerService pms) {
+ PackageVerificationResponse response, PackageManagerService pms) {
state.setVerifierResponse(response.callerUid, response.code);
+ processVerificationResponse(verificationId, state, response.code, "Install not allowed",
+ pms);
+ }
+
+ private static void processVerificationResponse(int verificationId,
+ PackageVerificationState state, int verificationResult, String failureReason,
+ PackageManagerService pms) {
if (!state.isVerificationComplete()) {
return;
}
final VerifyingSession verifyingSession = state.getVerifyingSession();
- final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile);
+ final Uri originUri = verifyingSession != null ? Uri.fromFile(
+ verifyingSession.mOriginInfo.mResolvedFile) : null;
final int verificationCode =
- state.isInstallAllowed() ? response.code : PackageManager.VERIFICATION_REJECT;
+ state.isInstallAllowed() ? verificationResult : PackageManager.VERIFICATION_REJECT;
- VerificationUtils.broadcastPackageVerified(verificationId, originUri,
- verificationCode, null,
- verifyingSession.getDataLoaderType(), verifyingSession.getUser(),
- pms.mContext);
+ if (pms != null && verifyingSession != null) {
+ VerificationUtils.broadcastPackageVerified(verificationId, originUri,
+ verificationCode, null,
+ verifyingSession.getDataLoaderType(), verifyingSession.getUser(),
+ pms.mContext);
+ }
if (state.isInstallAllowed()) {
Slog.i(TAG, "Continuing with installation of " + originUri);
} else {
String errorMsg = failureReason + " for " + originUri;
Slog.i(TAG, errorMsg);
- verifyingSession.setReturnCode(
- PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg);
+ if (verifyingSession != null) {
+ verifyingSession.setReturnCode(
+ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, errorMsg);
+ }
}
- if (state.areAllVerificationsComplete()) {
+ if (pms != null && state.areAllVerificationsComplete()) {
pms.mPendingVerification.remove(verificationId);
}
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
- verifyingSession.handleVerificationFinished();
+ if (verifyingSession != null) {
+ verifyingSession.handleVerificationFinished();
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 7f0c3f9..6e738da 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -16,7 +16,6 @@
package com.android.server.pm.dex;
-import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo;
import static com.android.server.pm.dex.PackageDexUsage.PackageUseInfo;
@@ -659,62 +658,6 @@
}
}
- // TODO(calin): questionable API in the presence of class loaders context. Needs amends as the
- // compilation happening here will use a pessimistic context.
- public RegisterDexModuleResult registerDexModule(ApplicationInfo info, String dexPath,
- boolean isSharedModule, int userId) throws LegacyDexoptDisabledException {
- // Find the owning package record.
- DexSearchResult searchResult = getDexPackage(info, dexPath, userId);
-
- if (searchResult.mOutcome == DEX_SEARCH_NOT_FOUND) {
- return new RegisterDexModuleResult(false, "Package not found");
- }
- if (!info.packageName.equals(searchResult.mOwningPackageName)) {
- return new RegisterDexModuleResult(false, "Dex path does not belong to package");
- }
- if (searchResult.mOutcome == DEX_SEARCH_FOUND_PRIMARY ||
- searchResult.mOutcome == DEX_SEARCH_FOUND_SPLIT) {
- return new RegisterDexModuleResult(false, "Main apks cannot be registered");
- }
-
- // We found the package. Now record the usage for all declared ISAs.
- boolean update = false;
- // If this is a shared module set the loading package to an arbitrary package name
- // so that we can mark that module as usedByOthers.
- String loadingPackage = isSharedModule ? ".shared.module" : searchResult.mOwningPackageName;
- for (String isa : getAppDexInstructionSets(info.primaryCpuAbi, info.secondaryCpuAbi)) {
- boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
- dexPath, userId, isa, /*primaryOrSplit*/ false,
- loadingPackage,
- PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT,
- /*overwriteCLC=*/ false);
- update |= newUpdate;
- }
- if (update) {
- mPackageDexUsage.maybeWriteAsync();
- }
-
- DexUseInfo dexUseInfo = mPackageDexUsage.getPackageUseInfo(searchResult.mOwningPackageName)
- .getDexUseInfoMap().get(dexPath);
-
- // Try to optimize the package according to the install reason.
- DexoptOptions options = new DexoptOptions(info.packageName,
- PackageManagerService.REASON_INSTALL, /*flags*/0);
-
- int result = mPackageDexOptimizer.dexOptSecondaryDexPath(info, dexPath, dexUseInfo,
- options);
-
- // If we fail to optimize the package log an error but don't propagate the error
- // back to the app. The app cannot do much about it and the background job
- // will rety again when it executes.
- // TODO(calin): there might be some value to return the error here but it may
- // cause red herrings since that doesn't mean the app cannot use the module.
- if (result != PackageDexOptimizer.DEX_OPT_FAILED) {
- Slog.e(TAG, "Failed to optimize dex module " + dexPath);
- }
- return new RegisterDexModuleResult(true, "Dex module registered successfully");
- }
-
/**
* Return all packages that contain records of secondary dex files.
*/
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index c0d71ac..579d4e3 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -26,10 +26,10 @@
]
},
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedPermissionsTest"
},
{
"include-filter": "android.permission.cts.PermissionMaxSdkVersionTest"
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 094e70f..9f1cb1a 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -29,16 +29,16 @@
]
},
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedPermissionsTest"
},
{
- "include-filter": "android.permission2.cts.RestrictedStoragePermissionSharedUidTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedStoragePermissionSharedUidTest"
},
{
- "include-filter": "android.permission2.cts.RestrictedStoragePermissionTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedStoragePermissionTest"
}
]
},
diff --git a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
index b05b662..d55fbc2 100644
--- a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
+++ b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.os.Handler;
import android.os.HandlerExecutor;
+import android.os.Trace;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.IndentingPrintWriter;
@@ -55,6 +56,7 @@
private static final String SUBSYSTEM_ALARM_STRING = "Alarm";
private static final String SUBSYSTEM_ALARM_WIFI = "Wifi";
+ private static final String TRACE_TRACK_WAKEUP_ATTRIBUTION = "wakeup_attribution";
@VisibleForTesting
static final long WAKEUP_REASON_HALF_WINDOW_MS = 500;
private static final long WAKEUP_WRITE_DELAY_MS = TimeUnit.MINUTES.toMillis(2);
@@ -94,13 +96,15 @@
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN;
}
- private synchronized void logWakeupToStatsLog(Wakeup wakeupToLog) {
+ private synchronized void logWakeupAttribution(Wakeup wakeupToLog) {
if (ArrayUtils.isEmpty(wakeupToLog.mDevices)) {
FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED,
FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__TYPE__TYPE_UNKNOWN,
FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN,
null,
wakeupToLog.mElapsedMillis);
+ Trace.instantForTrack(Trace.TRACE_TAG_POWER, TRACE_TRACK_WAKEUP_ATTRIBUTION,
+ wakeupToLog.mElapsedMillis + " --");
return;
}
@@ -112,6 +116,9 @@
Slog.wtf(TAG, "Unexpected null attribution found for " + wakeupToLog);
return;
}
+
+ final StringBuilder traceEventBuilder = new StringBuilder();
+
for (int i = 0; i < wakeupAttribution.size(); i++) {
final int subsystem = wakeupAttribution.keyAt(i);
final SparseBooleanArray uidMap = wakeupAttribution.valueAt(i);
@@ -132,7 +139,19 @@
subsystemToStatsReason(subsystem),
uids,
wakeupToLog.mElapsedMillis);
+
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_POWER)) {
+ if (i == 0) {
+ traceEventBuilder.append(wakeupToLog.mElapsedMillis + " ");
+ }
+ traceEventBuilder.append((subsystemToString(subsystem)));
+ traceEventBuilder.append(":");
+ traceEventBuilder.append(Arrays.toString(uids));
+ traceEventBuilder.append(" ");
+ }
}
+ Trace.instantForTrack(Trace.TRACE_TAG_POWER, TRACE_TRACK_WAKEUP_ATTRIBUTION,
+ traceEventBuilder.toString().trim());
}
/** Notes a wakeup reason as reported by SuspendControlService to battery stats. */
@@ -160,7 +179,7 @@
for (int i = lastIdx; i >= 0; i--) {
mWakeupAttribution.removeAt(i);
}
- mHandler.postDelayed(() -> logWakeupToStatsLog(parsedWakeup), WAKEUP_WRITE_DELAY_MS);
+ mHandler.postDelayed(() -> logWakeupAttribution(parsedWakeup), WAKEUP_WRITE_DELAY_MS);
}
/** Notes a waking activity that could have potentially woken up the CPU. */
diff --git a/services/core/java/com/android/server/powerstats/BatteryTrigger.java b/services/core/java/com/android/server/powerstats/BatteryTrigger.java
index b35cb52..15c1811 100644
--- a/services/core/java/com/android/server/powerstats/BatteryTrigger.java
+++ b/services/core/java/com/android/server/powerstats/BatteryTrigger.java
@@ -59,7 +59,9 @@
if (triggerEnabled) {
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = mContext.registerReceiver(mBatteryLevelReceiver, filter);
- mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ if (batteryStatus != null) {
+ mBatteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index 0d4a76e..fb400da 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -2887,7 +2887,7 @@
}
@Override
- public void onRequestScheduleRecording2(String inputId, String requestId, Uri channelUri,
+ public void onRequestScheduleRecording2(String requestId, String inputId, Uri channelUri,
long start, long duration, int repeat, Bundle params) {
synchronized (mLock) {
if (DEBUG) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 55060a6..f53b52c1 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -3560,6 +3560,9 @@
}
private void dumpWallpaper(WallpaperData wallpaper, PrintWriter pw) {
+ if (wallpaper == null) {
+ pw.println(" (null entry)");
+ }
pw.print(" User "); pw.print(wallpaper.userId);
pw.print(": id="); pw.print(wallpaper.wallpaperId);
pw.print(": mWhich="); pw.print(wallpaper.mWhich);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 62932f9..a327a42 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -121,6 +121,7 @@
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
+import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
@@ -5205,7 +5206,7 @@
Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
return;
}
- if (visible == mVisibleRequested && visible == mVisible
+ if (visible == mVisibleRequested && visible == mVisible && visible == isClientVisible()
&& mTransitionController.isShellTransitionsEnabled()) {
// For shell transition, it is no-op if there is no state change.
return;
@@ -8123,6 +8124,7 @@
mSizeCompatScale = 1f;
mSizeCompatBounds = null;
mCompatDisplayInsets = null;
+ mLetterboxUiController.clearInheritedCompatDisplayInsets();
}
@VisibleForTesting
@@ -8441,6 +8443,12 @@
}
}
+ @NonNull Rect getScreenResolvedBounds() {
+ final Configuration resolvedConfig = getResolvedOverrideConfiguration();
+ final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
+ return mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
+ }
+
void recomputeConfiguration() {
// We check if the current activity is transparent. In that case we need to
// recomputeConfiguration of the first opaque activity beneath, to allow a
@@ -8648,7 +8656,7 @@
resolvedBounds.set(containingBounds);
final float letterboxAspectRatioOverride =
- mLetterboxUiController.getFixedOrientationLetterboxAspectRatio();
+ mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig);
final float desiredAspectRatio =
letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
? letterboxAspectRatioOverride : computeAspectRatio(parentBounds);
@@ -9701,9 +9709,36 @@
return;
}
- if (getParent() != null) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ final Transition transition = new Transition(TRANSIT_RELAUNCH, 0 /* flags */,
+ mTransitionController, mWmService.mSyncEngine);
+ final Runnable executeRestart = () -> {
+ if (mState != RESTARTING_PROCESS || !attachedToProcess()) {
+ transition.abort();
+ return;
+ }
+ // Request invisible so there will be a change after the activity is restarted
+ // to be visible.
+ setVisibleRequested(false);
+ transition.collect(this);
+ mTransitionController.requestStartTransition(transition, task,
+ null /* remoteTransition */, null /* displayChange */);
+ scheduleStopForRestartProcess();
+ };
+ if (mWmService.mSyncEngine.hasActiveSync()) {
+ mWmService.mSyncEngine.queueSyncSet(
+ () -> mTransitionController.moveToCollecting(transition), executeRestart);
+ } else {
+ mTransitionController.moveToCollecting(transition);
+ executeRestart.run();
+ }
+ } else {
startFreezingScreen();
+ scheduleStopForRestartProcess();
}
+ }
+
+ private void scheduleStopForRestartProcess() {
// The process will be killed until the activity reports stopped with saved state (see
// {@link ActivityTaskManagerService.activityStopped}).
try {
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 90a4820..105b2bb 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -191,6 +191,9 @@
* Prepare to handle on transition start. Clear all temporary fields.
*/
void preTransitionStart() {
+ if (shouldDisableSnapshots()) {
+ return;
+ }
resetTmpFields();
}
@@ -283,6 +286,9 @@
* Called when the visibility of an app changes outside the regular app transition flow.
*/
void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
+ if (shouldDisableSnapshots()) {
+ return;
+ }
if (!visible) {
resetTmpFields();
addBelowTopActivityIfExist(appWindowToken.getTask(), mPendingRemoveActivity,
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 5e066fa..f8fb76a 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -50,8 +50,6 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.RemoteAnimationAdapter;
-import android.view.WindowManager;
-import android.window.RemoteTransition;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -562,9 +560,8 @@
final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea()
.getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
if (rootTask == null) return false;
- final RemoteTransition remote = options.getRemoteTransition();
final ActivityRecord r = rootTask.topRunningActivity();
- if (r == null || r.isVisibleRequested() || !r.attachedToProcess() || remote == null
+ if (r == null || r.isVisibleRequested() || !r.attachedToProcess()
|| !r.mActivityComponent.equals(intent.getComponent())
// Recents keeps invisible while device is locked.
|| r.mDisplayContent.isKeyguardLocked()) {
@@ -573,47 +570,13 @@
mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r);
final ActivityMetricsLogger.LaunchingState launchingState =
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
- final Transition transition = new Transition(WindowManager.TRANSIT_TO_FRONT,
- 0 /* flags */, r.mTransitionController, mService.mWindowManager.mSyncEngine);
- if (r.mTransitionController.isCollecting()) {
- // Special case: we are entering recents while an existing transition is running. In
- // this case, we know it's safe to "defer" the activity launch, so lets do so now so
- // that it can get its own transition and thus update launcher correctly.
- mService.mWindowManager.mSyncEngine.queueSyncSet(
- () -> {
- if (r.isAttached()) {
- r.mTransitionController.moveToCollecting(transition);
- }
- },
- () -> {
- if (r.isAttached() && transition.isCollecting()) {
- startExistingRecentsIfPossibleInner(options, r, rootTask,
- launchingState, remote, transition);
- }
- });
- } else {
- r.mTransitionController.moveToCollecting(transition);
- startExistingRecentsIfPossibleInner(options, r, rootTask, launchingState, remote,
- transition);
- }
- return true;
- }
-
- private void startExistingRecentsIfPossibleInner(ActivityOptions options, ActivityRecord r,
- Task rootTask, ActivityMetricsLogger.LaunchingState launchingState,
- RemoteTransition remoteTransition, Transition transition) {
final Task task = r.getTask();
mService.deferWindowLayout();
try {
final TransitionController controller = r.mTransitionController;
if (controller.getTransitionPlayer() != null) {
- controller.requestStartTransition(transition, task, remoteTransition,
- null /* displayChange */);
controller.collect(task);
controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
- } else {
- // The transition player might be died when executing the queued transition.
- transition.abort();
}
task.moveToFront("startExistingRecents");
task.mInResumeTopActivity = true;
@@ -624,6 +587,7 @@
task.mInResumeTopActivity = false;
mService.continueWindowLayout();
}
+ return true;
}
void registerRemoteAnimationForNextActivityStart(String packageName,
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index ce29564..12be1d3 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1582,19 +1582,19 @@
}
}
if (isTransientLaunch) {
- if (forceTransientTransition && newTransition != null) {
- newTransition.collect(mLastStartActivityRecord);
- newTransition.collect(mPriorAboveTask);
+ if (forceTransientTransition) {
+ transitionController.collect(mLastStartActivityRecord);
+ transitionController.collect(mPriorAboveTask);
}
// `started` isn't guaranteed to be the actual relevant activity, so we must wait
// until after we launched to identify the relevant activity.
transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
- if (forceTransientTransition && newTransition != null) {
+ if (forceTransientTransition) {
final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
// update wallpaper target to TransientHide
dc.mWallpaperController.adjustWallpaperWindows();
// execute transition because there is no change
- newTransition.setReady(dc, true /* ready */);
+ transitionController.setReady(dc, true /* ready */);
}
}
if (!userLeaving) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 992743a..555cd38 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1240,25 +1240,6 @@
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
- // A quick path (skip general intent/task resolving) to start recents animation if the
- // recents (or home) activity is available in background.
- if (opts != null && opts.getOriginalOptions().getTransientLaunch()
- && isCallerRecents(Binder.getCallingUid())) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (mGlobalLock) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
- if (mActivityStartController.startExistingRecentsIfPossible(
- intent, opts.getOriginalOptions())) {
- return ActivityManager.START_TASK_TO_FRONT;
- }
- // Else follow the standard launch procedure.
- }
- } finally {
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- Binder.restoreCallingIdentity(origId);
- }
- }
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
@@ -5718,6 +5699,23 @@
boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
BackgroundStartPrivileges backgroundStartPrivileges) {
assertPackageMatchesCallingUid(callingPackage);
+ // A quick path (skip general intent/task resolving) to start recents animation if the
+ // recents (or home) activity is available in background.
+ if (options != null && options.getOriginalOptions() != null
+ && options.getOriginalOptions().getTransientLaunch() && isCallerRecents(uid)) {
+ try {
+ synchronized (mGlobalLock) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
+ if (mActivityStartController.startExistingRecentsIfPossible(
+ intent, options.getOriginalOptions())) {
+ return ActivityManager.START_TASK_TO_FRONT;
+ }
+ // Else follow the standard launch procedure.
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
return getActivityStartController().startActivityInPackage(uid, realCallingPid,
realCallingUid, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, options, userId, inTask,
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 9e258cb..d358eb5 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -143,14 +143,15 @@
// Recording has already begun, but update recording since the display is now on.
if (mRecordedWindowContainer == null) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unexpectedly null window container; unable to update recording for "
- + "display %d",
+ "Content Recording: Unexpectedly null window container; unable to update "
+ + "recording for display %d",
mDisplayContent.getDisplayId());
return;
}
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Display %d was already recording, so apply transformations if necessary",
+ "Content Recording: Display %d was already recording, so apply "
+ + "transformations if necessary",
mDisplayContent.getDisplayId());
// Retrieve the size of the region to record, and continue with the update
// if the bounds or orientation has changed.
@@ -161,8 +162,8 @@
Point surfaceSize = fetchSurfaceSizeIfPresent();
if (surfaceSize != null) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Going ahead with updating recording for display %d to new "
- + "bounds %s and/or orientation %d.",
+ "Content Recording: Going ahead with updating recording for display "
+ + "%d to new bounds %s and/or orientation %d.",
mDisplayContent.getDisplayId(), recordedContentBounds,
recordedContentOrientation);
updateMirroredSurface(mDisplayContent.mWmService.mTransactionFactory.get(),
@@ -171,8 +172,9 @@
// If the surface removed, do nothing. We will handle this via onDisplayChanged
// (the display will be off if the surface is removed).
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to update recording for display %d to new bounds %s"
- + " and/or orientation %d, since the surface is not available.",
+ "Content Recording: Unable to update recording for display %d to new "
+ + "bounds %s and/or orientation %d, since the surface is not "
+ + "available.",
mDisplayContent.getDisplayId(), recordedContentBounds,
recordedContentOrientation);
}
@@ -189,8 +191,8 @@
return;
}
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Display %d has content (%b) so pause recording", mDisplayContent.getDisplayId(),
- mDisplayContent.getLastHasContent());
+ "Content Recording: Display %d has content (%b) so pause recording",
+ mDisplayContent.getDisplayId(), mDisplayContent.getLastHasContent());
// If the display is not on and it is a virtual display, then it no longer has an
// associated surface to write output to.
// If the display now has content, stop mirroring to it.
@@ -231,7 +233,8 @@
*/
private void stopMediaProjection() {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Stop MediaProjection on virtual display %d", mDisplayContent.getDisplayId());
+ "Content Recording: Stop MediaProjection on virtual display %d",
+ mDisplayContent.getDisplayId());
if (mMediaProjectionManager != null) {
mMediaProjectionManager.stopActiveProjection();
}
@@ -283,13 +286,14 @@
final Point surfaceSize = fetchSurfaceSizeIfPresent();
if (surfaceSize == null) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to start recording for display %d since the surface is not "
- + "available.",
+ "Content Recording: Unable to start recording for display %d since the "
+ + "surface is not available.",
mDisplayContent.getDisplayId());
return;
}
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Display %d has no content and is on, so start recording for state %d",
+ "Content Recording: Display %d has no content and is on, so start recording for "
+ + "state %d",
mDisplayContent.getDisplayId(), mDisplayContent.getDisplay().getState());
// Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
@@ -349,7 +353,7 @@
if (tokenToRecord == null) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to start recording due to null token for display %d",
+ "Content Recording: Unable to start recording due to null token for display %d",
mDisplayContent.getDisplayId());
return null;
}
@@ -359,13 +363,14 @@
mDisplayContent.mWmService.mWindowContextListenerController.getContainer(
tokenToRecord);
if (wc == null) {
- // Fall back to screenrecording using the data sent to DisplayManager
+ // Fall back to mirroring using the data sent to DisplayManager
mDisplayContent.mWmService.mDisplayManagerInternal.setWindowManagerMirroring(
mDisplayContent.getDisplayId(), false);
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to retrieve window container to start recording for "
- + "display %d", mDisplayContent.getDisplayId());
+ "Content Recording: Unable to retrieve window container to start "
+ + "recording for display %d",
+ mDisplayContent.getDisplayId());
return null;
}
// TODO(206461622) Migrate to using the RootDisplayArea
@@ -375,7 +380,7 @@
KEY_RECORD_TASK_FEATURE, false)) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to record task since feature is disabled %d",
+ "Content Recording: Unable to record task since feature is disabled %d",
mDisplayContent.getDisplayId());
return null;
}
@@ -383,8 +388,9 @@
if (taskToRecord == null) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to retrieve task to start recording for "
- + "display %d", mDisplayContent.getDisplayId());
+ "Content Recording: Unable to retrieve task to start recording for "
+ + "display %d",
+ mDisplayContent.getDisplayId());
} else {
taskToRecord.registerWindowContainerListener(this);
}
@@ -394,7 +400,8 @@
// capture for the entire display.
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Unable to start recording due to invalid region for display %d",
+ "Content Recording: Unable to start recording due to invalid region for "
+ + "display %d",
mDisplayContent.getDisplayId());
return null;
}
@@ -488,8 +495,8 @@
// State of virtual display will change to 'ON' when the surface is set.
// will get event DISPLAY_DEVICE_EVENT_CHANGED
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Provided surface for recording on display %d is not present, so do not"
- + " update the surface",
+ "Content Recording: Provided surface for recording on display %d is not "
+ + "present, so do not update the surface",
mDisplayContent.getDisplayId());
return null;
}
@@ -500,7 +507,7 @@
@Override
public void onRemoved() {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Recorded task is removed, so stop recording on display %d",
+ "Content Recording: Recorded task is removed, so stop recording on display %d",
mDisplayContent.getDisplayId());
unregisterListener();
@@ -551,8 +558,8 @@
mIMediaProjectionManager.stopActiveProjection();
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
- "Unable to tell MediaProjectionManagerService to stop the active "
- + "projection: %s",
+ "Content Recording: Unable to tell MediaProjectionManagerService to stop "
+ + "the active projection: %s",
e);
}
}
@@ -568,8 +575,8 @@
height);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
- "Unable to tell MediaProjectionManagerService about resizing the active "
- + "projection: %s",
+ "Content Recording: Unable to tell MediaProjectionManagerService about "
+ + "resizing the active projection: %s",
e);
}
}
@@ -585,8 +592,8 @@
isVisible);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
- "Unable to tell MediaProjectionManagerService about visibility change on "
- + "the active projection: %s",
+ "Content Recording: Unable to tell MediaProjectionManagerService about "
+ + "visibility change on the active projection: %s",
e);
}
}
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index 1efc202..d60addc 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -53,35 +53,59 @@
}
/**
- * Updates the current recording session. If a new display is taking over recording, then
- * stops the prior display from recording.
+ * Updates the current recording session.
+ * <p>Handles the following scenarios:
+ * <ul>
+ * <li>Invalid scenarios: The incoming session is malformed, or the incoming session is
+ * identical to the current session</li>
+ * <li>Start Scenario: Starting a new session. Recording begins immediately.</li>
+ * <li>Takeover Scenario: Occurs during a Start Scenario, if a pre-existing session was
+ * in-progress. For example, recording on VirtualDisplay "app_foo" was ongoing. A
+ * session for VirtualDisplay "app_bar" arrives. The controller stops the session on
+ * VirtualDisplay "app_foo" and allows the session for VirtualDisplay "app_bar" to
+ * begin.</li>
+ * <li>Stopping scenario: The incoming session is null and there is currently an ongoing
+ * session. The controller stops recording.</li>
+ * </ul>
*
- * @param incomingSession the new recording session. Should either have a {@code null} token, to
- * stop the current session, or a session on a new/different display
- * than the current session.
- * @param wmService the window manager service
+ * @param incomingSession The incoming recording session (either an update to a current session
+ * or a new session), or null to stop the current session.
+ * @param wmService The window manager service.
*/
void setContentRecordingSessionLocked(@Nullable ContentRecordingSession incomingSession,
@NonNull WindowManagerService wmService) {
- if (incomingSession != null && (!ContentRecordingSession.isValid(incomingSession)
- || ContentRecordingSession.isSameDisplay(mSession, incomingSession))) {
- // Ignore an invalid session, or a session for the same display as currently recording.
+ // Invalid scenario: ignore invalid incoming session.
+ if (incomingSession != null && !ContentRecordingSession.isValid(incomingSession)) {
+ return;
+ }
+ // Invalid scenario: ignore identical incoming session.
+ if (ContentRecordingSession.isProjectionOnSameDisplay(mSession, incomingSession)) {
+ // TODO(242833866) if incoming session is no longer waiting to record, allow
+ // the update through.
+
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Ignoring session on same display %d, with an existing "
+ + "session %s",
+ incomingSession.getDisplayId(), mSession.getDisplayId());
return;
}
DisplayContent incomingDisplayContent = null;
+ // Start scenario: recording begins immediately.
if (incomingSession != null) {
- // Recording will start on a new display, possibly taking over from a current session.
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Handle incoming session on display %d, with a pre-existing session %s",
- incomingSession.getDisplayId(),
+ "Content Recording: Handle incoming session on display %d, with a "
+ + "pre-existing session %s", incomingSession.getDisplayId(),
mSession == null ? null : mSession.getDisplayId());
incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
incomingSession.getDisplayId());
incomingDisplayContent.setContentRecordingSession(incomingSession);
+ // TODO(b/270118861) When user grants consent to re-use, explicitly ask ContentRecorder
+ // to update, since no config/display change arrives. Mark recording as black.
}
+ // Takeover and stopping scenario: stop recording on the pre-existing session.
if (mSession != null) {
- // Update the pre-existing display about the new session.
- ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Pause the recording session on display %s",
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Pause the recording session on display %s",
mDisplayContent.getDisplayId());
mDisplayContent.pauseRecording();
mDisplayContent.setContentRecordingSession(null);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a4d475f..ef01cc8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1228,7 +1228,8 @@
private void finishHoldScreenUpdate() {
final boolean hold = mTmpHoldScreenWindow != null;
if (hold && mTmpHoldScreenWindow != mHoldScreenWindow) {
- mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid));
+ mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid,
+ mTmpHoldScreenWindow.mSession.mPackageName));
}
mHoldScreenWindow = mTmpHoldScreenWindow;
mTmpHoldScreenWindow = null;
@@ -5935,7 +5936,7 @@
mOffTokenAcquirer.release(mDisplayId);
}
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Display %d state is now (%d), so update recording?",
+ "Content Recording: Display %d state is now (%d), so update recording?",
mDisplayId, displayState);
if (lastDisplayState != displayState) {
// If state is on due to surface being added, then start recording.
@@ -6560,7 +6561,7 @@
if (mirrorDisplayId == mDisplayId) {
if (mDisplayId != DEFAULT_DISPLAY) {
ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
- "Attempting to mirror self on %d", mirrorDisplayId);
+ "Content Recording: Attempting to mirror self on %d", mirrorDisplayId);
}
return false;
}
@@ -6570,16 +6571,18 @@
// to mirror the DEFAULT_DISPLAY so instead we just return
DisplayContent mirrorDc = mRootWindowContainer.getDisplayContentOrCreate(mirrorDisplayId);
if (mirrorDc == null && mDisplayId == DEFAULT_DISPLAY) {
- ProtoLog.w(WM_DEBUG_CONTENT_RECORDING, "Found no matching mirror display for id=%d for"
- + " DEFAULT_DISPLAY. Nothing to mirror.", mirrorDisplayId);
+ ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Found no matching mirror display for id=%d for "
+ + "DEFAULT_DISPLAY. Nothing to mirror.",
+ mirrorDisplayId);
return false;
}
if (mirrorDc == null) {
mirrorDc = mRootWindowContainer.getDefaultDisplay();
ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
- "Attempting to mirror %d from %d but no DisplayContent associated. Changing "
- + "to mirror default display.",
+ "Content Recording: Attempting to mirror %d from %d but no DisplayContent "
+ + "associated. Changing to mirror default display.",
mirrorDisplayId, mDisplayId);
}
@@ -6588,8 +6591,8 @@
.setDisplayId(mDisplayId);
setContentRecordingSession(session);
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Successfully created a ContentRecordingSession for displayId=%d to mirror "
- + "content from displayId=%d",
+ "Content Recording: Successfully created a ContentRecordingSession for "
+ + "displayId=%d to mirror content from displayId=%d",
mDisplayId, mirrorDisplayId);
return true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 389c908..c719a1d 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -19,7 +19,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.Display.TYPE_INTERNAL;
-import static android.view.InsetsFrameProvider.SOURCE_FRAME;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -179,6 +178,7 @@
private final boolean mCarDockEnablesAccelerometer;
private final boolean mDeskDockEnablesAccelerometer;
+ private final boolean mDeskDockRespectsNoSensorAndLockedWithoutAccelerometer;
private final AccessibilityManager mAccessibilityManager;
private final ImmersiveModeConfirmation mImmersiveModeConfirmation;
private final ScreenshotHelper mScreenshotHelper;
@@ -388,6 +388,8 @@
final Resources r = mContext.getResources();
mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
+ mDeskDockRespectsNoSensorAndLockedWithoutAccelerometer =
+ r.getBoolean(R.bool.config_deskRespectsNoSensorAndLockedWithoutAccelerometer);
mCanSystemBarsBeShownByUser = !r.getBoolean(
R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean(
R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction);
@@ -699,6 +701,10 @@
return mDeskDockEnablesAccelerometer;
}
+ boolean isDeskDockRespectsNoSensorAndLockedWithoutAccelerometer() {
+ return mDeskDockRespectsNoSensorAndLockedWithoutAccelerometer;
+ }
+
public void setPersistentVrModeEnabled(boolean persistentVrModeEnabled) {
mPersistentVrModeEnabled = persistentVrModeEnabled;
}
@@ -1069,7 +1075,7 @@
// runtime as ensured in WMS. Make use of the index in the provider directly
// to access the latest provided size at runtime.
final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider =
- getFrameProvider(win, provider, i);
+ getFrameProvider(win, i);
final InsetsFrameProvider.InsetsSizeOverride[] overrides =
provider.getInsetsSizeOverrides();
final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
@@ -1095,19 +1101,15 @@
}
}
- @Nullable
private TriConsumer<DisplayFrames, WindowContainer, Rect> getFrameProvider(WindowState win,
- InsetsFrameProvider provider, int index) {
- if (provider.getInsetsSize() == null && provider.getSource() == SOURCE_FRAME) {
- return null;
- }
+ int index) {
return (displayFrames, windowContainer, inOutFrame) -> {
final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation);
final InsetsFrameProvider ifp = lp.providedInsets[index];
InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted,
windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame,
ifp.getSource(), ifp.getInsetsSize(), lp.privateFlags,
- ifp.getMinimalInsetsSizeInDisplayCutoutSafe());
+ ifp.getMinimalInsetsSizeInDisplayCutoutSafe(), win.mGivenContentInsets);
};
}
@@ -1120,7 +1122,8 @@
InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted,
windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame,
ifp.getSource(), ifp.getInsetsSizeOverrides()[overrideIndex].getInsetsSize(),
- lp.privateFlags, null /* displayCutoutSafeInsetsSize */);
+ lp.privateFlags, null /* displayCutoutSafeInsetsSize */,
+ null /* givenContentInsets */);
};
}
@@ -2447,6 +2450,8 @@
pw.print("mCarDockEnablesAccelerometer="); pw.print(mCarDockEnablesAccelerometer);
pw.print(" mDeskDockEnablesAccelerometer=");
pw.println(mDeskDockEnablesAccelerometer);
+ pw.print(" mDeskDockRespectsNoSensorAndLockedWithoutAccelerometer=");
+ pw.println(mDeskDockRespectsNoSensorAndLockedWithoutAccelerometer);
pw.print(prefix); pw.print("mDockMode="); pw.print(Intent.dockStateToString(mDockMode));
pw.print(" mLidState="); pw.println(WindowManagerFuncs.lidStateToString(mLidState));
pw.print(prefix); pw.print("mAwake="); pw.print(mAwake);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 06d108b..72263ff 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -87,6 +87,12 @@
*/
public class DisplayRotation {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
+ // Delay to avoid race between fold update and orientation update.
+ private static final int ORIENTATION_UPDATE_DELAY_MS = 800;
+
+ // Delay in milliseconds when updating config due to folding events. This prevents
+ // config changes and unexpected jumps while folding the device to closed state.
+ private static final int FOLDING_RECOMPUTE_CONFIG_DELAY_MS = 800;
private static class RotationAnimationPair {
@AnimRes
@@ -1194,6 +1200,10 @@
mDisplayPolicy.isCarDockEnablesAccelerometer();
final boolean deskDockEnablesAccelerometer =
mDisplayPolicy.isDeskDockEnablesAccelerometer();
+ final boolean deskDockRespectsNoSensorAndLockedWithoutAccelerometer =
+ mDisplayPolicy.isDeskDockRespectsNoSensorAndLockedWithoutAccelerometer()
+ && (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
@Surface.Rotation
final int preferredRotation;
@@ -1213,7 +1223,8 @@
} else if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
|| dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
|| dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
+ && (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)
+ && !deskDockRespectsNoSensorAndLockedWithoutAccelerometer) {
// Ignore sensor when in desk dock unless explicitly enabled.
// This case can override the behavior of NOSENSOR, and can also
// enable 180 degree rotation while docked.
@@ -1662,6 +1673,7 @@
private boolean mInHalfFoldTransition = false;
private final boolean mIsDisplayAlwaysSeparatingHinge;
private final Set<Integer> mTabletopRotations;
+ private final Runnable mActivityBoundsUpdateCallback;
FoldController() {
mTabletopRotations = new ArraySet<>();
@@ -1696,6 +1708,26 @@
}
mIsDisplayAlwaysSeparatingHinge = mContext.getResources().getBoolean(
R.bool.config_isDisplayHingeAlwaysSeparating);
+
+ mActivityBoundsUpdateCallback = new Runnable() {
+ public void run() {
+ if (mDeviceState == DeviceStateController.DeviceState.OPEN
+ || mDeviceState == DeviceStateController.DeviceState.HALF_FOLDED) {
+ synchronized (mLock) {
+ final Task topFullscreenTask =
+ mDisplayContent.getTask(
+ t -> t.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+ if (topFullscreenTask != null) {
+ final ActivityRecord top =
+ topFullscreenTask.topRunningActivity();
+ if (top != null) {
+ top.recomputeConfiguration();
+ }
+ }
+ }
+ }
+ }
+ };
}
boolean isDeviceInPosture(DeviceStateController.DeviceState state, boolean isTabletop) {
@@ -1757,24 +1789,19 @@
mDeviceState = newState;
// Now mFoldState is set to HALF_FOLDED, the overrideFrozenRotation function will
// return true, so rotation is unlocked.
- mService.updateRotation(false /* alwaysSendConfiguration */,
- false /* forceRelayout */);
} else {
mInHalfFoldTransition = true;
mDeviceState = newState;
- // Tell the device to update its orientation.
- mService.updateRotation(false /* alwaysSendConfiguration */,
- false /* forceRelayout */);
}
+ UiThread.getHandler().postDelayed(
+ () -> {
+ mService.updateRotation(false /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }, ORIENTATION_UPDATE_DELAY_MS);
// Alert the activity of possible new bounds.
- final Task topFullscreenTask =
- mDisplayContent.getTask(t -> t.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
- if (topFullscreenTask != null) {
- final ActivityRecord top = topFullscreenTask.topRunningActivity();
- if (top != null) {
- top.recomputeConfiguration();
- }
- }
+ UiThread.getHandler().removeCallbacks(mActivityBoundsUpdateCallback);
+ UiThread.getHandler().postDelayed(mActivityBoundsUpdateCallback,
+ FOLDING_RECOMPUTE_CONFIG_DELAY_MS);
}
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8f40e79..0b960ec 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -419,8 +419,12 @@
if (mInputFocus != recentsAnimationInputConsumer.mWindowHandle.token) {
requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
recentsAnimationInputConsumer.mName);
+ }
+ if (mDisplayContent.mInputMethodWindow != null
+ && mDisplayContent.mInputMethodWindow.isVisible()) {
// Hiding IME/IME icon when recents input consumer gain focus.
- if (!mDisplayContent.isImeAttachedToApp()) {
+ final boolean isImeAttachedToApp = mDisplayContent.isImeAttachedToApp();
+ if (!isImeAttachedToApp) {
// Hiding IME if IME window is not attached to app since it's not proper to
// snapshot Task with IME window to animate together in this case.
final InputMethodManagerInternal inputMethodManagerInternal =
@@ -429,6 +433,14 @@
inputMethodManagerInternal.hideCurrentInputMethod(
SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
}
+ // Ensure removing the IME snapshot when the app no longer to show on the
+ // task snapshot (also taking the new task snaphot to update the overview).
+ final ActivityRecord app = mDisplayContent.getImeInputTarget() != null
+ ? mDisplayContent.getImeInputTarget().getActivityRecord() : null;
+ if (app != null) {
+ mDisplayContent.removeImeSurfaceImmediately();
+ mDisplayContent.mAtmService.takeTaskSnapshot(app.getTask().mTaskId);
+ }
} else {
// Disable IME icon explicitly when IME attached to the app in case
// IME icon might flickering while swiping to the next app task still
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 37cf5bc..ec04894 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -184,6 +184,10 @@
// portrait device orientation.
private boolean mIsVerticalReachabilityEnabled;
+ // Whether book mode automatic horizontal reachability positioning is allowed for letterboxed
+ // fullscreen apps in landscape device orientation.
+ private boolean mIsAutomaticReachabilityInBookModeEnabled;
+
// Whether education is allowed for letterboxed fullscreen apps.
private boolean mIsEducationEnabled;
@@ -277,6 +281,8 @@
R.bool.config_letterboxIsHorizontalReachabilityEnabled);
mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsVerticalReachabilityEnabled);
+ mIsAutomaticReachabilityInBookModeEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsAutomaticReachabilityInBookModeEnabled);
mDefaultPositionForHorizontalReachability =
readLetterboxHorizontalReachabilityPositionFromConfig(mContext, false);
mDefaultPositionForVerticalReachability =
@@ -681,6 +687,14 @@
return mIsVerticalReachabilityEnabled;
}
+ /*
+ * Whether automatic horizontal reachability repositioning in book mode is allowed for
+ * letterboxed fullscreen apps in landscape device orientation.
+ */
+ boolean getIsAutomaticReachabilityInBookModeEnabled() {
+ return mIsAutomaticReachabilityInBookModeEnabled;
+ }
+
/**
* Overrides whether horizontal reachability repositioning is allowed for letterboxed fullscreen
* apps in landscape device orientation.
@@ -698,6 +712,14 @@
}
/**
+ * Overrides whether automatic horizontal reachability repositioning in book mode is allowed for
+ * letterboxed fullscreen apps in landscape device orientation.
+ */
+ void setIsAutomaticReachabilityInBookModeEnabled(boolean enabled) {
+ mIsAutomaticReachabilityInBookModeEnabled = enabled;
+ }
+
+ /**
* Resets whether horizontal reachability repositioning is allowed for letterboxed fullscreen
* apps in landscape device orientation to
* {@link R.bool.config_letterboxIsHorizontalReachabilityEnabled}.
@@ -717,6 +739,16 @@
R.bool.config_letterboxIsVerticalReachabilityEnabled);
}
+ /**
+ * Resets whether automatic horizontal reachability repositioning in book mode is
+ * allowed for letterboxed fullscreen apps in landscape device orientation to
+ * {@link R.bool.config_letterboxIsAutomaticReachabilityInBookModeEnabled}.
+ */
+ void resetEnabledAutomaticReachabilityInBookMode() {
+ mIsAutomaticReachabilityInBookModeEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsAutomaticReachabilityInBookModeEnabled);
+ }
+
/*
* Gets default horizontal position of the letterboxed app window when horizontal reachability
* is enabled.
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index ef464d2..d8a6d49 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -22,6 +22,7 @@
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
@@ -38,6 +39,10 @@
import static android.content.pm.ActivityInfo.screenOrientationToString;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
+import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
+import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
@@ -126,6 +131,14 @@
private static final float UNDEFINED_ASPECT_RATIO = 0f;
+ // Minimum value of mSetOrientationRequestCounter before qualifying as orientation request loop
+ @VisibleForTesting
+ static final int MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP = 2;
+ // Used to determine reset of mSetOrientationRequestCounter if next app requested
+ // orientation is after timeout value
+ @VisibleForTesting
+ static final int SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS = 1000;
+
private final Point mTmpPoint = new Point();
private final LetterboxConfiguration mLetterboxConfiguration;
@@ -158,6 +171,8 @@
// Corresponds to OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION
private final boolean mIsOverrideEnableCompatIgnoreRequestedOrientationEnabled;
+ // Corresponds to OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED
+ private final boolean mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled;
// Corresponds to OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS
private final boolean mIsOverrideEnableCompatFakeFocusEnabled;
@@ -182,12 +197,18 @@
private float mInheritedMinAspectRatio = UNDEFINED_ASPECT_RATIO;
private float mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;
+ // Updated when ActivityRecord#setRequestedOrientation is called
+ private long mTimeMsLastSetOrientationRequest = 0;
+
@Configuration.Orientation
- private int mInheritedOrientation = Configuration.ORIENTATION_UNDEFINED;
+ private int mInheritedOrientation = ORIENTATION_UNDEFINED;
// The app compat state for the opaque activity if any
private int mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
+ // Counter for ActivityRecord#setRequestedOrientation
+ private int mSetOrientationRequestCounter = 0;
+
// The CompatDisplayInsets of the opaque activity beneath the translucent one.
private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;
@@ -280,6 +301,9 @@
mIsOverrideEnableCompatIgnoreRequestedOrientationEnabled =
isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+ mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled =
+ isCompatChangeEnabled(
+ OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
mIsOverrideEnableCompatFakeFocusEnabled =
isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS);
@@ -315,6 +339,10 @@
mLetterbox.destroy();
mLetterbox = null;
}
+ if (mLetterboxConfigListener != null) {
+ mLetterboxConfigListener.onRemoved();
+ mLetterboxConfigListener = null;
+ }
}
void onMovedToDisplay(int displayId) {
@@ -346,38 +374,88 @@
* <li>Opt-in component property or per-app override are enabled
* <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
* call from an app or camera compat force rotation treatment is active for the activity.
+ * <li>Orientation request loop detected and is not letterboxed for fixed orientation
* </ul>
*/
boolean shouldIgnoreRequestedOrientation(@ScreenOrientation int requestedOrientation) {
- if (!shouldEnableWithOverrideAndProperty(
+ if (shouldEnableWithOverrideAndProperty(
/* gatingCondition */ mLetterboxConfiguration
::isPolicyForIgnoringRequestedOrientationEnabled,
mIsOverrideEnableCompatIgnoreRequestedOrientationEnabled,
mBooleanPropertyIgnoreRequestedOrientation)) {
- return false;
+ if (mIsRelauchingAfterRequestedOrientationChanged) {
+ Slog.w(TAG, "Ignoring orientation update to "
+ + screenOrientationToString(requestedOrientation)
+ + " due to relaunching after setRequestedOrientation for "
+ + mActivityRecord);
+ return true;
+ }
+ DisplayContent displayContent = mActivityRecord.mDisplayContent;
+ if (displayContent == null) {
+ return false;
+ }
+ if (displayContent.mDisplayRotationCompatPolicy != null
+ && displayContent.mDisplayRotationCompatPolicy
+ .isTreatmentEnabledForActivity(mActivityRecord)) {
+ Slog.w(TAG, "Ignoring orientation update to "
+ + screenOrientationToString(requestedOrientation)
+ + " due to camera compat treatment for " + mActivityRecord);
+ return true;
+ }
}
- if (mIsRelauchingAfterRequestedOrientationChanged) {
+
+ if (shouldIgnoreOrientationRequestLoop()) {
Slog.w(TAG, "Ignoring orientation update to "
+ screenOrientationToString(requestedOrientation)
- + " due to relaunching after setRequestedOrientation for " + mActivityRecord);
- return true;
- }
- DisplayContent displayContent = mActivityRecord.mDisplayContent;
- if (displayContent == null) {
- return false;
- }
- if (displayContent.mDisplayRotationCompatPolicy != null
- && displayContent.mDisplayRotationCompatPolicy
- .isTreatmentEnabledForActivity(mActivityRecord)) {
- Slog.w(TAG, "Ignoring orientation update to "
- + screenOrientationToString(requestedOrientation)
- + " due to camera compat treatment for " + mActivityRecord);
+ + " as orientation request loop was detected for "
+ + mActivityRecord);
return true;
}
return false;
}
/**
+ * Whether an app is calling {@link android.app.Activity#setRequestedOrientation}
+ * in a loop and orientation request should be ignored.
+ *
+ * <p>This should only be called once in response to
+ * {@link android.app.Activity#setRequestedOrientation}. See
+ * {@link #shouldIgnoreRequestedOrientation} for more details.
+ *
+ * <p>This treatment is enabled when the following conditions are met:
+ * <ul>
+ * <li>Per-app override is enabled
+ * <li>App has requested orientation more than 2 times within 1-second
+ * timer and activity is not letterboxed for fixed orientation
+ * </ul>
+ */
+ @VisibleForTesting
+ boolean shouldIgnoreOrientationRequestLoop() {
+ if (!mIsOverrideEnableCompatIgnoreOrientationRequestWhenLoopDetectedEnabled) {
+ return false;
+ }
+
+ final long currTimeMs = System.currentTimeMillis();
+ if (currTimeMs - mTimeMsLastSetOrientationRequest
+ < SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS) {
+ mSetOrientationRequestCounter += 1;
+ } else {
+ // Resets app setOrientationRequest counter if timed out
+ mSetOrientationRequestCounter = 0;
+ }
+ // Update time last called
+ mTimeMsLastSetOrientationRequest = currTimeMs;
+
+ return mSetOrientationRequestCounter >= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP
+ && !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
+ }
+
+ @VisibleForTesting
+ int getSetOrientationRequestCounter() {
+ return mSetOrientationRequestCounter;
+ }
+
+ /**
* Whether sending compat fake focus for split screen resumed activities is enabled. Needed
* because some game engines wait to get focus before drawing the content of the app which isn't
* guaranteed by default in multi-window modes.
@@ -741,6 +819,8 @@
final Rect innerFrame = hasInheritedLetterboxBehavior()
? mActivityRecord.getBounds() : w.getFrame();
mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
+ // We need to notify Shell that letterbox position has changed.
+ mActivityRecord.getTask().dispatchTaskInfoChangedIfNeeded(true /* force */);
} else if (mLetterbox != null) {
mLetterbox.hide();
}
@@ -789,13 +869,18 @@
float getHorizontalPositionMultiplier(Configuration parentConfiguration) {
// Don't check resolved configuration because it may not be updated yet during
// configuration change.
- boolean bookMode = isDisplayFullScreenAndInPosture(
- DeviceStateController.DeviceState.HALF_FOLDED, false /* isTabletop */);
+ boolean bookModeEnabled = isFullScreenAndBookModeEnabled();
return isHorizontalReachabilityEnabled(parentConfiguration)
// Using the last global dynamic position to avoid "jumps" when moving
// between apps or activities.
- ? mLetterboxConfiguration.getHorizontalMultiplierForReachability(bookMode)
- : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(bookMode);
+ ? mLetterboxConfiguration.getHorizontalMultiplierForReachability(bookModeEnabled)
+ : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier(bookModeEnabled);
+ }
+
+ private boolean isFullScreenAndBookModeEnabled() {
+ return isDisplayFullScreenAndInPosture(
+ DeviceStateController.DeviceState.HALF_FOLDED, false /* isTabletop */)
+ && mLetterboxConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
}
float getVerticalPositionMultiplier(Configuration parentConfiguration) {
@@ -810,12 +895,14 @@
: mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier(tabletopMode);
}
- float getFixedOrientationLetterboxAspectRatio() {
+ float getFixedOrientationLetterboxAspectRatio(@NonNull Configuration parentConfiguration) {
+ // Don't resize to split screen size when half folded if letterbox position is centered
return isDisplayFullScreenAndSeparatingHinge()
- ? getSplitScreenAspectRatio()
- : mActivityRecord.shouldCreateCompatDisplayInsets()
- ? getDefaultMinAspectRatioForUnresizableApps()
- : getDefaultMinAspectRatio();
+ && getHorizontalPositionMultiplier(parentConfiguration) != 0.5f
+ ? getSplitScreenAspectRatio()
+ : mActivityRecord.shouldCreateCompatDisplayInsets()
+ ? getDefaultMinAspectRatioForUnresizableApps()
+ : getDefaultMinAspectRatio();
}
private float getDefaultMinAspectRatioForUnresizableApps() {
@@ -866,6 +953,20 @@
return mActivityRecord.mWmService.mContext.getResources();
}
+ @LetterboxConfiguration.LetterboxVerticalReachabilityPosition
+ int getLetterboxPositionForVerticalReachability() {
+ final boolean isInFullScreenTabletopMode = isDisplayFullScreenAndSeparatingHinge();
+ return mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(
+ isInFullScreenTabletopMode);
+ }
+
+ @LetterboxConfiguration.LetterboxHorizontalReachabilityPosition
+ int getLetterboxPositionForHorizontalReachability() {
+ final boolean isInFullScreenBookMode = isDisplayFullScreenAndSeparatingHinge();
+ return mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(
+ isInFullScreenBookMode);
+ }
+
@VisibleForTesting
void handleHorizontalDoubleTap(int x) {
if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
@@ -877,7 +978,8 @@
return;
}
- boolean isInFullScreenBookMode = isDisplayFullScreenAndSeparatingHinge();
+ boolean isInFullScreenBookMode = isDisplayFullScreenAndSeparatingHinge()
+ && mLetterboxConfiguration.getIsAutomaticReachabilityInBookModeEnabled();
int letterboxPositionForHorizontalReachability = mLetterboxConfiguration
.getLetterboxPositionForHorizontalReachability(isInFullScreenBookMode);
if (mLetterbox.getInnerFrame().left > x) {
@@ -957,6 +1059,8 @@
* </ul>
*/
private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) {
+ // Use screen resolved bounds which uses resolved bounds or size compat bounds
+ // as activity bounds can sometimes be empty
return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()
&& parentConfiguration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FULLSCREEN
@@ -964,7 +1068,7 @@
&& mActivityRecord.getOrientationForReachability() == ORIENTATION_PORTRAIT)
// Check whether the activity fills the parent vertically.
&& parentConfiguration.windowConfiguration.getAppBounds().height()
- <= mActivityRecord.getBounds().height();
+ <= mActivityRecord.getScreenResolvedBounds().height();
}
@VisibleForTesting
@@ -972,6 +1076,10 @@
return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
}
+ boolean isLetterboxDoubleTapEducationEnabled() {
+ return isHorizontalReachabilityEnabled() || isVerticalReachabilityEnabled();
+ }
+
/**
* Whether vertical reachability is enabled for an activity in the current configuration.
*
@@ -984,6 +1092,8 @@
* </ul>
*/
private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) {
+ // Use screen resolved bounds which uses resolved bounds or size compat bounds
+ // as activity bounds can sometimes be empty
return mLetterboxConfiguration.getIsVerticalReachabilityEnabled()
&& parentConfiguration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FULLSCREEN
@@ -991,7 +1101,7 @@
&& mActivityRecord.getOrientationForReachability() == ORIENTATION_LANDSCAPE)
// Check whether the activity fills the parent horizontally.
&& parentConfiguration.windowConfiguration.getBounds().width()
- == mActivityRecord.getBounds().width();
+ == mActivityRecord.getScreenResolvedBounds().width();
}
@VisibleForTesting
@@ -1409,7 +1519,8 @@
mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation(
mActivityRecord, firstOpaqueActivityBeneath,
(opaqueConfig, transparentConfig) -> {
- final Configuration mutatedConfiguration = new Configuration();
+ final Configuration mutatedConfiguration =
+ fromOriginalTranslucentConfig(transparentConfig);
final Rect parentBounds = parent.getWindowConfiguration().getBounds();
final Rect bounds = mutatedConfiguration.windowConfiguration.getBounds();
final Rect letterboxBounds = opaqueConfig.windowConfiguration.getBounds();
@@ -1471,6 +1582,10 @@
return mInheritedCompatDisplayInsets;
}
+ void clearInheritedCompatDisplayInsets() {
+ mInheritedCompatDisplayInsets = null;
+ }
+
/**
* In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque
* activity beneath using the given consumer and returns {@code true}.
@@ -1497,6 +1612,22 @@
true /* traverseTopToBottom */));
}
+ // When overriding translucent activities configuration we need to keep some of the
+ // original properties
+ private Configuration fromOriginalTranslucentConfig(Configuration translucentConfig) {
+ final Configuration configuration = new Configuration(translucentConfig);
+ // The values for the following properties will be defined during the configuration
+ // resolution in {@link ActivityRecord#resolveOverrideConfiguration} using the
+ // properties inherited from the first not finishing opaque activity beneath.
+ configuration.orientation = ORIENTATION_UNDEFINED;
+ configuration.screenWidthDp = configuration.compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
+ configuration.screenHeightDp =
+ configuration.compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
+ configuration.smallestScreenWidthDp =
+ configuration.compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
+ return configuration;
+ }
+
private void inheritConfiguration(ActivityRecord firstOpaque) {
// To avoid wrong behaviour, we're not forcing a specific aspect ratio to activities
// which are not already providing one (e.g. permission dialogs) and presumably also
@@ -1516,7 +1647,7 @@
mLetterboxConfigListener = null;
mInheritedMinAspectRatio = UNDEFINED_ASPECT_RATIO;
mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;
- mInheritedOrientation = Configuration.ORIENTATION_UNDEFINED;
+ mInheritedOrientation = ORIENTATION_UNDEFINED;
mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
mInheritedCompatDisplayInsets = null;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fda2125..2f56343 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2281,11 +2281,10 @@
resumedOnDisplay[0] |= curResult;
return;
}
- if (rootTask.getDisplayArea().isTopRootTask(rootTask)
- && topRunningActivity.isState(RESUMED)) {
- // Kick off any lingering app transitions from the MoveTaskToFront
- // operation, but only consider the top task and root-task on that
- // display.
+ if (topRunningActivity.isState(RESUMED)
+ && topRunningActivity == rootTask.getDisplayArea().topRunningActivity()) {
+ // Kick off any lingering app transitions form the MoveTaskToFront operation,
+ // but only consider the top activity on that display.
rootTask.executeAppTransition(targetOptions);
} else {
resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 78ee6f9..7b10c63 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -116,7 +116,7 @@
private boolean mShowingAlertWindowNotificationAllowed;
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
- private String mPackageName;
+ protected String mPackageName;
private String mRelayoutTag;
private final InsetsSourceControl.Array mDummyControls = new InsetsSourceControl.Array();
final boolean mSetsUnrestrictedKeepClearAreas;
diff --git a/services/core/java/com/android/server/wm/SnapshotController.java b/services/core/java/com/android/server/wm/SnapshotController.java
index cd1263e..badcfa9 100644
--- a/services/core/java/com/android/server/wm/SnapshotController.java
+++ b/services/core/java/com/android/server/wm/SnapshotController.java
@@ -213,8 +213,12 @@
void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
if (!visible && hasTransitionStateConsumer(TASK_CLOSE)) {
+ final Task task = appWindowToken.getTask();
+ if (task == null || task.isVisibleRequested()) {
+ return;
+ }
// close task transition
- addTransitionRecord(TASK_CLOSE, false /*open*/, appWindowToken.getTask());
+ addTransitionRecord(TASK_CLOSE, false /*open*/, task);
mActivitySnapshotController.preTransitionStart();
notifyTransition(TASK_CLOSE);
mActivitySnapshotController.postTransitionStart();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 68b2d0f..699e02e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3392,6 +3392,25 @@
info.isFocused = isFocused();
info.isVisible = hasVisibleChildren();
info.isSleeping = shouldSleepActivities();
+ info.isLetterboxDoubleTapEnabled = top != null
+ && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();
+ info.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
+ info.topActivityLetterboxHeight = TaskInfo.PROPERTY_VALUE_UNSET;
+ if (info.isLetterboxDoubleTapEnabled) {
+ info.topActivityLetterboxWidth = top.getBounds().width();
+ info.topActivityLetterboxHeight = top.getBounds().height();
+ if (info.topActivityLetterboxWidth < info.topActivityLetterboxHeight) {
+ // Pillarboxed
+ info.topActivityLetterboxHorizontalPosition =
+ top.mLetterboxUiController.getLetterboxPositionForHorizontalReachability();
+ } else {
+ // Letterboxed
+ info.topActivityLetterboxVerticalPosition =
+ top.mLetterboxUiController.getLetterboxPositionForVerticalReachability();
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 6bc9fa4..612fc4b 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2553,13 +2553,18 @@
return task != null && !task.isDragResizing() && super.canStartChangeTransition();
}
- /** Records the starting bounds of the closing organized TaskFragment. */
- void setClosingChangingStartBoundsIfNeeded() {
+ /**
+ * Returns {@code true} if the starting bounds of the closing organized TaskFragment is
+ * recorded. Otherwise, return {@code false}.
+ */
+ boolean setClosingChangingStartBoundsIfNeeded() {
if (isOrganizedTaskFragment() && mDisplayContent != null
&& mDisplayContent.mChangingContainers.remove(this)) {
mDisplayContent.mClosingChangingContainers.put(
this, new Rect(mSurfaceFreezer.mFreezeBounds));
+ return true;
}
+ return false;
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 93c8c36..184293e 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -390,7 +390,7 @@
boolean taskAppearedSent = t.mTaskAppearedSent;
if (taskAppearedSent) {
if (t.getSurfaceControl() != null) {
- t.migrateToNewSurfaceControl(t.getSyncTransaction());
+ t.migrateToNewSurfaceControl(t.getPendingTransaction());
}
t.mTaskAppearedSent = false;
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index ba49dd0..2cfd2af8 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1227,7 +1227,13 @@
// transferred. If transition is transient, IME won't be moved during the transition and
// the tasks are still live, so we take the snapshot at the end of the transition instead.
if (mTransientLaunches == null) {
- mController.mSnapshotController.onTransitionReady(mType, mParticipants);
+ for (int i = mParticipants.size() - 1; i >= 0; --i) {
+ final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
+ if (ar == null || ar.getTask() == null
+ || ar.getTask().isVisibleRequested()) continue;
+ mController.mSnapshotController.mTaskSnapshotController.recordSnapshot(
+ ar.getTask(), false /* allowSnapshotHome */);
+ }
}
// This is non-null only if display has changes. It handles the visible windows that don't
@@ -2732,9 +2738,7 @@
buffer, screenshotBuffer.getColorSpace());
}
SurfaceControl.Transaction t = wc.mWmService.mTransactionFactory.get();
-
- t.setBuffer(snapshotSurface, buffer);
- t.setDataSpace(snapshotSurface, screenshotBuffer.getColorSpace().getDataSpace());
+ TransitionAnimation.configureScreenshotLayer(t, snapshotSurface, screenshotBuffer);
t.show(snapshotSurface);
// Place it on top of anything else in the container.
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d42a629..520d06d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1336,14 +1336,18 @@
// If we are losing visibility, then a snapshot isn't necessary and we are no-longer
// part of a change transition.
if (!visible) {
+ boolean skipUnfreeze = false;
if (asTaskFragment() != null) {
// If the organized TaskFragment is closing while resizing, we want to keep track of
// its starting bounds to make sure the animation starts at the correct position.
// This should be called before unfreeze() because we record the starting bounds
// in SurfaceFreezer.
- asTaskFragment().setClosingChangingStartBoundsIfNeeded();
+ skipUnfreeze = asTaskFragment().setClosingChangingStartBoundsIfNeeded();
}
- mSurfaceFreezer.unfreeze(getSyncTransaction());
+
+ if (!skipUnfreeze) {
+ mSurfaceFreezer.unfreeze(getSyncTransaction());
+ }
}
WindowContainer parent = getParent();
if (parent != null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 61685fc..a55c7c1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8703,7 +8703,13 @@
} else {
h.touchableRegion.set(region);
h.replaceTouchableRegionWithCrop = false;
- h.setTouchableRegionCrop(surface);
+
+ // Task managers may need to receive input events around task layers to resize tasks.
+ final int permissionResult = mContext.checkPermission(
+ permission.MANAGE_ACTIVITY_TASKS, callingPid, callingUid);
+ if (permissionResult != PackageManager.PERMISSION_GRANTED) {
+ h.setTouchableRegionCrop(surface);
+ }
}
final SurfaceControl.Transaction t = mTransactionFactory.get();
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 8c2dd2d..437af4b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -981,6 +981,10 @@
runSetBooleanFlag(pw, mLetterboxConfiguration
::setIsVerticalReachabilityEnabled);
break;
+ case "--isAutomaticReachabilityInBookModeEnabled":
+ runSetBooleanFlag(pw, mLetterboxConfiguration
+ ::setIsAutomaticReachabilityInBookModeEnabled);
+ break;
case "--defaultPositionForHorizontalReachability":
runSetLetterboxDefaultPositionForHorizontalReachability(pw);
break;
@@ -1183,6 +1187,7 @@
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
+ mLetterboxConfiguration.resetEnabledAutomaticReachabilityInBookMode();
mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability();
mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
mLetterboxConfiguration.resetIsEducationEnabled();
@@ -1218,6 +1223,8 @@
+ mLetterboxConfiguration.getIsHorizontalReachabilityEnabled());
pw.println("Is vertical reachability enabled: "
+ mLetterboxConfiguration.getIsVerticalReachabilityEnabled());
+ pw.println("Is automatic reachability in book mode enabled: "
+ + mLetterboxConfiguration.getIsAutomaticReachabilityInBookModeEnabled());
pw.println("Default position for horizontal reachability: "
+ LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString(
mLetterboxConfiguration.getDefaultPositionForHorizontalReachability()));
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 8b0ef6c..c74af82 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -439,7 +439,11 @@
// multiple sync at the same time because it may cause conflict.
// Create a new transition when there is no active sync to collect the changes.
final Transition transition = mTransitionController.createTransition(type);
- applyTransaction(wct, -1 /* syncId */, transition, caller);
+ if (applyTransaction(wct, -1 /* syncId */, transition, caller)
+ == TRANSACT_EFFECTS_NONE && transition.mParticipants.isEmpty()) {
+ transition.abort();
+ return;
+ }
mTransitionController.requestStartTransition(transition, null /* startTask */,
null /* remoteTransition */, null /* displayChange */);
transition.setAllReady();
@@ -476,24 +480,26 @@
// calls startSyncSet.
() -> mTransitionController.moveToCollecting(nextTransition),
() -> {
- if (mTaskFragmentOrganizerController.isValidTransaction(wct)) {
- applyTransaction(wct, -1 /*syncId*/, nextTransition, caller);
+ if (mTaskFragmentOrganizerController.isValidTransaction(wct)
+ && (applyTransaction(wct, -1 /* syncId */, nextTransition, caller)
+ != TRANSACT_EFFECTS_NONE
+ || !nextTransition.mParticipants.isEmpty())) {
mTransitionController.requestStartTransition(nextTransition,
null /* startTask */, null /* remoteTransition */,
null /* displayChange */);
nextTransition.setAllReady();
- } else {
- nextTransition.abort();
+ return;
}
+ nextTransition.abort();
});
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+ private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller) {
- applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
+ return applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
}
/**
@@ -501,8 +507,9 @@
* @param transition A transition to collect changes into.
* @param caller Info about the calling process.
* @param finishTransition The transition that is currently being finished.
+ * @return The effects of the window container transaction.
*/
- private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+ private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller,
@Nullable Transition finishTransition) {
int effects = TRANSACT_EFFECTS_NONE;
@@ -639,6 +646,7 @@
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
mService.continueWindowLayout();
}
+ return effects;
}
private int applyChanges(@NonNull WindowContainer<?> container,
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 06fe4f0..687c861 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -16,6 +16,7 @@
package com.android.server.credentials;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -31,6 +32,7 @@
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
+import android.service.credentials.PermissionUtils;
import android.util.Log;
import com.android.server.credentials.metrics.ApiName;
@@ -88,7 +90,9 @@
mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
RequestInfo.newCreateRequestInfo(
mRequestId, mClientRequest,
- mClientAppInfo.getPackageName()),
+ mClientAppInfo.getPackageName(),
+ PermissionUtils.hasPermission(mContext, mClientAppInfo.getPackageName(),
+ Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)),
providerDataList));
} catch (RemoteException e) {
mChosenProviderFinalPhaseMetric.setUiReturned(false);
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index a15d6630..90b92f4 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -42,8 +42,9 @@
import android.credentials.ICreateCredentialCallback;
import android.credentials.ICredentialManager;
import android.credentials.IGetCredentialCallback;
-import android.credentials.IGetPendingCredentialCallback;
+import android.credentials.IPrepareGetCredentialCallback;
import android.credentials.ISetEnabledProvidersCallback;
+import android.credentials.PrepareGetCredentialResponseInternal;
import android.credentials.RegisterCredentialDescriptionRequest;
import android.credentials.UnregisterCredentialDescriptionRequest;
import android.credentials.ui.IntentFactory;
@@ -307,6 +308,29 @@
return providerSessions;
}
+ @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
+ // to be guarded by 'service.mLock', which is the same as mLock.
+ private List<ProviderSession> initiateProviderSessionsWithActiveContainers(
+ PrepareGetRequestSession session,
+ Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>>
+ activeCredentialContainers) {
+ List<ProviderSession> providerSessions = new ArrayList<>();
+ for (Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult> result :
+ activeCredentialContainers) {
+ ProviderSession providerSession = ProviderRegistryGetSession.createNewSession(
+ mContext,
+ UserHandle.getCallingUserId(),
+ session,
+ session.mClientAppInfo,
+ result.second.mPackageName,
+ result.first);
+ providerSessions.add(providerSession);
+ session.addProviderSession(providerSession.getComponentName(), providerSession);
+ }
+ return providerSessions;
+ }
+
+
@NonNull
private Set<Pair<CredentialOption, CredentialDescriptionRegistry.FilterResult>>
getFilteredResultFromRegistry(List<CredentialOption> options) {
@@ -443,21 +467,122 @@
}
@Override
- public ICancellationSignal executeGetPendingCredential(
+ public ICancellationSignal executePrepareGetCredential(
GetCredentialRequest request,
- IGetPendingCredentialCallback callback,
+ IPrepareGetCredentialCallback prepareGetCredentialCallback,
+ IGetCredentialCallback getCredentialCallback,
final String callingPackage) {
- // TODO(b/273308895): implement
-
+ final long timestampBegan = System.nanoTime();
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+ if (request.getOrigin() != null) {
+ // Check privileged permissions
+ mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
+ }
enforcePermissionForAllowedProviders(request);
+ final int userId = UserHandle.getCallingUserId();
+ final int callingUid = Binder.getCallingUid();
+ enforceCallingPackage(callingPackage, callingUid);
+
+ final PrepareGetRequestSession session =
+ new PrepareGetRequestSession(
+ getContext(),
+ userId,
+ callingUid,
+ prepareGetCredentialCallback,
+ getCredentialCallback,
+ request,
+ constructCallingAppInfo(callingPackage, userId, request.getOrigin()),
+ CancellationSignal.fromTransport(cancelTransport),
+ timestampBegan);
+
+ processGetCredential(request, prepareGetCredentialCallback, session);
+
return cancelTransport;
}
private void processGetCredential(
GetCredentialRequest request,
+ IPrepareGetCredentialCallback callback,
+ PrepareGetRequestSession session) {
+ List<ProviderSession> providerSessions;
+
+ if (isCredentialDescriptionApiEnabled()) {
+ List<CredentialOption> optionsThatRequireActiveCredentials =
+ request.getCredentialOptions().stream()
+ .filter(
+ getCredentialOption ->
+ !TextUtils.isEmpty(
+ getCredentialOption
+ .getCredentialRetrievalData()
+ .getString(
+ CredentialOption
+ .FLATTENED_REQUEST,
+ null)))
+ .toList();
+
+ List<CredentialOption> optionsThatDoNotRequireActiveCredentials =
+ request.getCredentialOptions().stream()
+ .filter(
+ getCredentialOption ->
+ TextUtils.isEmpty(
+ getCredentialOption
+ .getCredentialRetrievalData()
+ .getString(
+ CredentialOption
+ .FLATTENED_REQUEST,
+ null)))
+ .toList();
+
+ List<ProviderSession> sessionsWithoutRemoteService =
+ initiateProviderSessionsWithActiveContainers(
+ session,
+ getFilteredResultFromRegistry(optionsThatRequireActiveCredentials));
+
+ List<ProviderSession> sessionsWithRemoteService =
+ initiateProviderSessions(
+ session,
+ optionsThatDoNotRequireActiveCredentials.stream()
+ .map(CredentialOption::getType)
+ .collect(Collectors.toList()));
+
+ Set<ProviderSession> all = new LinkedHashSet<>();
+ all.addAll(sessionsWithRemoteService);
+ all.addAll(sessionsWithoutRemoteService);
+
+ providerSessions = new ArrayList<>(all);
+ } else {
+ // Initiate all provider sessions
+ providerSessions =
+ initiateProviderSessions(
+ session,
+ request.getCredentialOptions().stream()
+ .map(CredentialOption::getType)
+ .collect(Collectors.toList()));
+ }
+
+ if (providerSessions.isEmpty()) {
+ try {
+ // TODO: fix
+ callback.onResponse(new PrepareGetCredentialResponseInternal(
+ false, null, false, false, null));
+ } catch (RemoteException e) {
+ Log.i(
+ TAG,
+ "Issue invoking onError on IGetCredentialCallback "
+ + "callback: "
+ + e.getMessage());
+ }
+ }
+
+ finalizeAndEmitInitialPhaseMetric(session);
+ // TODO(b/271135048) - May still be worth emitting in the empty cases above.
+ providerSessions.forEach(ProviderSession::invokeSession);
+ }
+
+ private void processGetCredential(
+ GetCredentialRequest request,
IGetCredentialCallback callback,
GetRequestSession session) {
List<ProviderSession> providerSessions;
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index 4e058a8..8082cdb 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -27,6 +27,7 @@
import android.credentials.IGetCredentialCallback;
import android.credentials.ui.ProviderData;
import android.credentials.ui.RequestInfo;
+import android.os.Binder;
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
@@ -84,11 +85,12 @@
protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime());
try {
- mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
+ Binder.withCleanCallingIdentity(() ->
+ mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
RequestInfo.newGetRequestInfo(
- mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
- providerDataList));
- } catch (RemoteException e) {
+ mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
+ providerDataList)));
+ } catch (RuntimeException e) {
mChosenProviderFinalPhaseMetric.setUiReturned(false);
respondToClientWithErrorAndFinish(
GetCredentialException.TYPE_UNKNOWN, "Unable to instantiate selector");
diff --git a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
new file mode 100644
index 0000000..b746784
--- /dev/null
+++ b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
@@ -0,0 +1,308 @@
+/*
+ * 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.credentials;
+
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.credentials.CredentialOption;
+import android.credentials.CredentialProviderInfo;
+import android.credentials.GetCredentialException;
+import android.credentials.GetCredentialRequest;
+import android.credentials.GetCredentialResponse;
+import android.credentials.IGetCredentialCallback;
+import android.credentials.IPrepareGetCredentialCallback;
+import android.credentials.PrepareGetCredentialResponseInternal;
+import android.credentials.ui.ProviderData;
+import android.credentials.ui.RequestInfo;
+import android.os.CancellationSignal;
+import android.os.RemoteException;
+import android.service.credentials.CallingAppInfo;
+import android.util.Log;
+
+import com.android.server.credentials.metrics.ApiName;
+import com.android.server.credentials.metrics.ProviderStatusForMetrics;
+
+import java.util.ArrayList;
+import java.util.stream.Collectors;
+
+/**
+ * Central session for a single prepareGetCredentials request. This class listens to the
+ * responses from providers, and the UX app, and updates the provider(S) state.
+ */
+public class PrepareGetRequestSession extends RequestSession<GetCredentialRequest,
+ IGetCredentialCallback>
+ implements ProviderSession.ProviderInternalCallback<GetCredentialResponse> {
+ private static final String TAG = "GetRequestSession";
+
+ private final IPrepareGetCredentialCallback mPrepareGetCredentialCallback;
+ private boolean mIsInitialQuery = true;
+
+ public PrepareGetRequestSession(Context context, int userId, int callingUid,
+ IPrepareGetCredentialCallback prepareGetCredentialCallback,
+ IGetCredentialCallback getCredCallback, GetCredentialRequest request,
+ CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal,
+ long startedTimestamp) {
+ super(context, userId, callingUid, request, getCredCallback, RequestInfo.TYPE_GET,
+ callingAppInfo, cancellationSignal, startedTimestamp);
+ int numTypes = (request.getCredentialOptions().stream()
+ .map(CredentialOption::getType).collect(
+ Collectors.toSet())).size(); // Dedupe type strings
+ setupInitialPhaseMetric(ApiName.GET_CREDENTIAL.getMetricCode(), numTypes);
+ mPrepareGetCredentialCallback = prepareGetCredentialCallback;
+ }
+
+ /**
+ * Creates a new provider session, and adds it list of providers that are contributing to
+ * this session.
+ *
+ * @return the provider session created within this request session, for the given provider
+ * info.
+ */
+ @Override
+ @Nullable
+ public ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,
+ RemoteCredentialService remoteCredentialService) {
+ ProviderGetSession providerGetSession = ProviderGetSession
+ .createNewSession(mContext, mUserId, providerInfo,
+ this, remoteCredentialService);
+ if (providerGetSession != null) {
+ Log.i(TAG, "In startProviderSession - provider session created and being added");
+ mProviders.put(providerGetSession.getComponentName().flattenToString(),
+ providerGetSession);
+ }
+ return providerGetSession;
+ }
+
+ @Override
+ protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
+ mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime());
+ try {
+ mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
+ RequestInfo.newGetRequestInfo(
+ mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
+ providerDataList));
+ } catch (RemoteException e) {
+ mChosenProviderFinalPhaseMetric.setUiReturned(false);
+ respondToClientWithErrorAndFinish(
+ GetCredentialException.TYPE_UNKNOWN, "Unable to instantiate selector");
+ }
+ }
+
+ @Override
+ public void onFinalResponseReceived(ComponentName componentName,
+ @Nullable GetCredentialResponse response) {
+ mChosenProviderFinalPhaseMetric.setUiReturned(true);
+ mChosenProviderFinalPhaseMetric.setUiCallEndTimeNanoseconds(System.nanoTime());
+ Log.i(TAG, "onFinalCredentialReceived from: " + componentName.flattenToString());
+ setChosenMetric(componentName);
+ if (response != null) {
+ mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
+ ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode());
+ respondToClientWithResponseAndFinish(response);
+ } else {
+ mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
+ ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode());
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "Invalid response from provider");
+ }
+ }
+
+ //TODO: Try moving the three error & response methods below to RequestSession to be shared
+ // between get & create.
+ @Override
+ public void onFinalErrorReceived(ComponentName componentName, String errorType,
+ String message) {
+ respondToClientWithErrorAndFinish(errorType, message);
+ }
+
+ private void respondToClientWithResponseAndFinish(GetCredentialResponse response) {
+ if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
+ Log.i(TAG, "Request has already been completed. This is strange.");
+ return;
+ }
+ if (isSessionCancelled()) {
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
+// ApiStatus.CLIENT_CANCELED);
+ finishSession(/*propagateCancellation=*/true);
+ return;
+ }
+ try {
+ mClientCallback.onResponse(response);
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
+// ApiStatus.SUCCESS);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage());
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
+// ApiStatus.FAILURE);
+ }
+ finishSession(/*propagateCancellation=*/false);
+ }
+
+ private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
+ if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
+ Log.i(TAG, "Request has already been completed. This is strange.");
+ return;
+ }
+ if (isSessionCancelled()) {
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
+// ApiStatus.CLIENT_CANCELED);
+ finishSession(/*propagateCancellation=*/true);
+ return;
+ }
+
+ try {
+ mClientCallback.onError(errorType, errorMsg);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Issue while responding to client with error : " + e.getMessage());
+ }
+ logFailureOrUserCancel(errorType);
+ finishSession(/*propagateCancellation=*/false);
+ }
+
+ private void logFailureOrUserCancel(String errorType) {
+ if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL,
+// /* apiStatus */ ApiStatus.USER_CANCELED);
+ } else {
+// TODO: properly log the new api
+// logApiCall(ApiName.GET_CREDENTIAL,
+// /* apiStatus */ ApiStatus.FAILURE);
+ }
+ }
+
+ @Override
+ public void onUiCancellation(boolean isUserCancellation) {
+ if (isUserCancellation) {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_USER_CANCELED,
+ "User cancelled the selector");
+ } else {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_INTERRUPTED,
+ "The UI was interrupted - please try again.");
+ }
+ }
+
+ @Override
+ public void onUiSelectorInvocationFailure() {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available.");
+ }
+
+ @Override
+ public void onProviderStatusChanged(ProviderSession.Status status,
+ ComponentName componentName) {
+ Log.i(TAG, "in onStatusChanged with status: " + status);
+ // Auth entry was selected, and it did not have any underlying credentials
+ if (status == ProviderSession.Status.NO_CREDENTIALS_FROM_AUTH_ENTRY) {
+ handleEmptyAuthenticationSelection(componentName);
+ return;
+ }
+ // For any other status, we check if all providers are done and then invoke UI if needed
+ if (!isAnyProviderPending()) {
+ // If all provider responses have been received, we can either need the UI,
+ // or we need to respond with error. The only other case is the entry being
+ // selected after the UI has been invoked which has a separate code path.
+ if (isUiInvocationNeeded()) {
+ if (mIsInitialQuery) {
+ try {
+ mPrepareGetCredentialCallback.onResponse(
+ new PrepareGetCredentialResponseInternal(
+ false, null,
+ false, false,
+ getUiIntent()));
+ } catch (Exception e) {
+ Log.e(TAG, "EXCEPTION while mPendingCallback.onResponse", e);
+ }
+ mIsInitialQuery = false;
+ } else {
+ getProviderDataAndInitiateUi();
+ }
+ } else {
+ if (mIsInitialQuery) {
+ try {
+ mPrepareGetCredentialCallback.onResponse(
+ new PrepareGetCredentialResponseInternal(
+ false, null, false, false, null));
+ } catch (Exception e) {
+ Log.e(TAG, "EXCEPTION while mPendingCallback.onResponse", e);
+ }
+ mIsInitialQuery = false;
+ // TODO(273308895): should also clear session here
+ } else {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available");
+ }
+ }
+ }
+ }
+
+ private PendingIntent getUiIntent() {
+ ArrayList<ProviderData> providerDataList = new ArrayList<>();
+ for (ProviderSession session : mProviders.values()) {
+ Log.i(TAG, "preparing data for : " + session.getComponentName());
+ ProviderData providerData = session.prepareUiData();
+ if (providerData != null) {
+ Log.i(TAG, "Provider data is not null");
+ providerDataList.add(providerData);
+ }
+ }
+ if (!providerDataList.isEmpty()) {
+ return mCredentialManagerUi.createPendingIntent(
+ RequestInfo.newGetRequestInfo(
+ mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
+ providerDataList);
+ } else {
+ return null;
+ }
+ }
+
+ private void handleEmptyAuthenticationSelection(ComponentName componentName) {
+ // Update auth entry statuses across different provider sessions
+ mProviders.keySet().forEach(key -> {
+ ProviderGetSession session = (ProviderGetSession) mProviders.get(key);
+ if (!session.mComponentName.equals(componentName)) {
+ session.updateAuthEntriesStatusFromAnotherSession();
+ }
+ });
+
+ // Invoke UI since it needs to show a snackbar if last auth entry, or a status on each
+ // auth entries along with other valid entries
+ getProviderDataAndInitiateUi();
+
+ // Respond to client if all auth entries are empty and nothing else to show on the UI
+ if (providerDataContainsEmptyAuthEntriesOnly()) {
+ respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+ "No credentials available");
+ }
+ }
+
+ private boolean providerDataContainsEmptyAuthEntriesOnly() {
+ for (String key : mProviders.keySet()) {
+ ProviderGetSession session = (ProviderGetSession) mProviders.get(key);
+ if (!session.containsEmptyAuthEntriesOnly()) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 95b0ff0..fcc0904 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -95,7 +95,42 @@
android.credentials.GetCredentialRequest filteredRequest =
filterOptions(providerInfo.getCapabilities(),
getRequestSession.mClientRequest,
- providerInfo.getComponentName());
+ providerInfo);
+ if (filteredRequest != null) {
+ Map<String, CredentialOption> beginGetOptionToCredentialOptionMap =
+ new HashMap<>();
+ return new ProviderGetSession(
+ context,
+ providerInfo,
+ getRequestSession,
+ userId,
+ remoteCredentialService,
+ constructQueryPhaseRequest(
+ filteredRequest, getRequestSession.mClientAppInfo,
+ getRequestSession.mClientRequest.alwaysSendAppInfoToProvider(),
+ beginGetOptionToCredentialOptionMap),
+ filteredRequest,
+ getRequestSession.mClientAppInfo,
+ beginGetOptionToCredentialOptionMap,
+ getRequestSession.mHybridService
+ );
+ }
+ Log.i(TAG, "Unable to create provider session");
+ return null;
+ }
+
+ /** Creates a new provider session to be used by the request session. */
+ @Nullable
+ public static ProviderGetSession createNewSession(
+ Context context,
+ @UserIdInt int userId,
+ CredentialProviderInfo providerInfo,
+ PrepareGetRequestSession getRequestSession,
+ RemoteCredentialService remoteCredentialService) {
+ android.credentials.GetCredentialRequest filteredRequest =
+ filterOptions(providerInfo.getCapabilities(),
+ getRequestSession.mClientRequest,
+ providerInfo);
if (filteredRequest != null) {
Map<String, CredentialOption> beginGetOptionToCredentialOptionMap =
new HashMap<>();
@@ -144,12 +179,13 @@
private static android.credentials.GetCredentialRequest filterOptions(
List<String> providerCapabilities,
android.credentials.GetCredentialRequest clientRequest,
- ComponentName componentName
+ CredentialProviderInfo info
) {
List<CredentialOption> filteredOptions = new ArrayList<>();
for (CredentialOption option : clientRequest.getCredentialOptions()) {
if (providerCapabilities.contains(option.getType())
- && isProviderAllowed(option, componentName)) {
+ && isProviderAllowed(option, info.getComponentName())
+ && checkSystemProviderRequirement(option, info.isSystemProvider())) {
Log.i(TAG, "In createProviderRequest - capability found : "
+ option.getType());
filteredOptions.add(option);
@@ -178,6 +214,15 @@
return true;
}
+ private static boolean checkSystemProviderRequirement(CredentialOption option,
+ boolean isSystemProvider) {
+ if (option.isSystemProviderRequired() && !isSystemProvider) {
+ Log.d(TAG, "System provider required, but this service is not a system provider");
+ return false;
+ }
+ return true;
+ }
+
public ProviderGetSession(Context context,
CredentialProviderInfo info,
ProviderInternalCallback<GetCredentialResponse> callbacks,
diff --git a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
index a5196c5..85c78445 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
@@ -76,6 +76,24 @@
requestOption);
}
+ /** Creates a new provider session to be used by the request session. */
+ @Nullable
+ public static ProviderRegistryGetSession createNewSession(
+ @NonNull Context context,
+ @UserIdInt int userId,
+ @NonNull PrepareGetRequestSession getRequestSession,
+ @NonNull CallingAppInfo callingAppInfo,
+ @NonNull String credentialProviderPackageName,
+ @NonNull CredentialOption requestOption) {
+ return new ProviderRegistryGetSession(
+ context,
+ userId,
+ getRequestSession,
+ callingAppInfo,
+ credentialProviderPackageName,
+ requestOption);
+ }
+
@NonNull
private final Map<String, CredentialEntry> mUiCredentialEntries = new HashMap<>();
@NonNull
@@ -106,6 +124,23 @@
.getString(CredentialOption.FLATTENED_REQUEST);
}
+ protected ProviderRegistryGetSession(@NonNull Context context,
+ @NonNull int userId,
+ @NonNull PrepareGetRequestSession session,
+ @NonNull CallingAppInfo callingAppInfo,
+ @NonNull String servicePackageName,
+ @NonNull CredentialOption requestOption) {
+ super(context, requestOption, session,
+ new ComponentName(servicePackageName, servicePackageName) ,
+ userId, null);
+ mCredentialDescriptionRegistry = CredentialDescriptionRegistry.forUser(userId);
+ mCallingAppInfo = callingAppInfo;
+ mCredentialProviderPackageName = servicePackageName;
+ mFlattenedRequestOptionString = requestOption
+ .getCredentialRetrievalData()
+ .getString(CredentialOption.FLATTENED_REQUEST);
+ }
+
private List<Entry> prepareUiCredentialEntries(
@NonNull List<CredentialEntry> credentialEntries) {
Log.i(TAG, "in prepareUiProviderDataWithCredentials");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e9c50b5..2479646 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -225,6 +225,7 @@
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
+import static android.provider.DeviceConfig.NAMESPACE_TELEPHONY;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -426,6 +427,7 @@
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.ParcelableKeyGenParameterSpec;
import android.stats.devicepolicy.DevicePolicyEnums;
+import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
@@ -473,6 +475,7 @@
import com.android.modules.utils.TypedXmlSerializer;
import com.android.net.module.util.ProxyUtils;
import com.android.server.AlarmManagerInternal;
+import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.PersistentDataBlockManagerInternal;
@@ -483,6 +486,7 @@
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.pm.DefaultCrossProfileIntentFilter;
import com.android.server.pm.DefaultCrossProfileIntentFiltersUtils;
+import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.RestrictionsSet;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
@@ -1616,6 +1620,10 @@
return LocalServices.getService(PackageManagerInternal.class);
}
+ PackageManagerLocal getPackageManagerLocal() {
+ return LocalManagerRegistry.getManager(PackageManagerLocal.class);
+ }
+
ActivityTaskManagerInternal getActivityTaskManagerInternal() {
return LocalServices.getService(ActivityTaskManagerInternal.class);
}
@@ -3324,7 +3332,7 @@
onLockSettingsReady();
loadAdminDataAsync();
mOwners.systemReady();
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
applyManagedSubscriptionsPolicyIfRequired();
}
break;
@@ -3534,26 +3542,21 @@
userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId);
updatePermissionPolicyCache(userId);
updateAdminCanGrantSensorsPermissionCache(userId);
- final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
- boolean isManagedSubscription;
+ final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
synchronized (getLockObject()) {
ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
preferentialNetworkServiceConfigs = owner != null
? owner.mPreferentialNetworkServiceConfigs
: List.of(PreferentialNetworkServiceConfig.DEFAULT);
-
- isManagedSubscription = owner != null && owner.mManagedSubscriptionsPolicy != null
- && owner.mManagedSubscriptionsPolicy.getPolicyType()
- == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS;
}
updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs);
- if (isManagedSubscription) {
- String defaultDialerPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultDialer);
- String defaultSmsPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultSms);
+ if (isProfileOwnerOfOrganizationOwnedDevice(userId)
+ && getManagedSubscriptionsPolicy().getPolicyType()
+ == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
+ String defaultDialerPackageName = getOemDefaultDialerPackage();
+ String defaultSmsPackageName = getOemDefaultSmsPackage();
updateDialerAndSmsManagedShortcutsOverrideCache(defaultDialerPackageName,
defaultSmsPackageName);
}
@@ -7640,7 +7643,7 @@
}
mLockSettingsInternal.refreshStrongAuthTimeout(parentId);
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
clearManagedSubscriptionsPolicy();
clearLauncherShortcutOverrides();
updateTelephonyCrossProfileIntentFilters(parentId, UserHandle.USER_NULL, false);
@@ -10991,8 +10994,10 @@
synchronized (mSubscriptionsChangedListenerLock) {
pw.println("Subscription changed listener : " + mSubscriptionsChangedListener);
}
- pw.println(
- "Flag enable_work_profile_telephony : " + isWorkProfileTelephonyFlagEnabled());
+ pw.println("DPM Flag enable_work_profile_telephony : "
+ + isWorkProfileTelephonyDevicePolicyManagerFlagEnabled());
+ pw.println("Telephony Flag enable_work_profile_telephony : "
+ + isWorkProfileTelephonySubscriptionManagerFlagEnabled());
mHandler.post(() -> handleDump(pw));
dumpResources(pw);
@@ -16355,19 +16360,26 @@
// The per-Q behavior was to not check the app-ops state.
granted = mIPackageManager.checkPermission(permission, packageName, userId);
} else {
- try {
- int uid = mInjector.getPackageManager().getPackageUidAsUser(
- packageName, userId);
- if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
- PermissionChecker.PID_UNKNOWN, uid, packageName)
- != PermissionChecker.PERMISSION_GRANTED) {
- granted = PackageManager.PERMISSION_DENIED;
+ try (var snapshot = mInjector.getPackageManagerLocal().withUnfilteredSnapshot()) {
+ var packageState = snapshot.getPackageStates().get(packageName);
+ if (packageState == null) {
+ Slog.w(LOG_TAG, "Can't get permission state for missing package "
+ + packageName);
+ return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+ } else if (!packageState.getUserStateOrDefault(userId).isInstalled()) {
+ Slog.w(LOG_TAG, "Can't get permission state for uninstalled package "
+ + packageName);
+ return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
} else {
- granted = PackageManager.PERMISSION_GRANTED;
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN,
+ UserHandle.getUid(userId, packageState.getAppId()), packageName)
+ != PermissionChecker.PERMISSION_GRANTED) {
+ granted = PackageManager.PERMISSION_DENIED;
+ } else {
+ granted = PackageManager.PERMISSION_GRANTED;
+ }
}
- } catch (NameNotFoundException e) {
- // Package does not exit
- return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
}
}
int permFlags = mInjector.getPackageManager().getPermissionFlags(
@@ -19345,23 +19357,29 @@
@Override
public boolean isPackageAllowedToAccessCalendarForUser(String packageName,
- int userHandle) {
+ @UserIdInt int userId) {
if (!mHasFeature) {
return false;
}
Preconditions.checkStringNotEmpty(packageName, "Package name is null or empty");
- Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId");
+ Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
- final CallerIdentity caller = getCallerIdentity();
- final int packageUid = mInjector.binderWithCleanCallingIdentity(() -> {
- try {
- return mInjector.getPackageManager().getPackageUidAsUser(packageName, userHandle);
- } catch (NameNotFoundException e) {
- Slogf.w(LOG_TAG, e,
- "Couldn't find package %s in user %d", packageName, userHandle);
- return -1;
+ final int packageUid;
+ try (var snapshot = mInjector.getPackageManagerLocal().withUnfilteredSnapshot()) {
+ var packageState = snapshot.getPackageStates().get(packageName);
+ if (packageState == null) {
+ Slogf.w(LOG_TAG, "Couldn't find package %s in user %d", packageName,
+ userId);
+ return false;
+ } else if (!packageState.getUserStateOrDefault(userId).isInstalled()) {
+ Slogf.w(LOG_TAG, "Couldn't find installed package %s in user %d", packageName,
+ userId);
+ return false;
+ } else {
+ packageUid = UserHandle.getUid(userId, packageState.getAppId());
}
- });
+ }
+ final CallerIdentity caller = getCallerIdentity();
if (caller.getUid() != packageUid) {
Preconditions.checkCallAuthorization(
hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)
@@ -19370,10 +19388,10 @@
synchronized (getLockObject()) {
if (mInjector.settingsSecureGetIntForUser(
- Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 0, userHandle) == 0) {
+ Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 0, userId) == 0) {
return false;
}
- final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
+ final ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
if (admin != null) {
if (admin.mCrossProfileCalendarPackages == null) {
return true;
@@ -19727,16 +19745,19 @@
}
private boolean isCallingFromPackage(String packageName, int callingUid) {
- return mInjector.binderWithCleanCallingIdentity(() -> {
- try {
- final int packageUid = mInjector.getPackageManager().getPackageUidAsUser(
- packageName, UserHandle.getUserId(callingUid));
- return packageUid == callingUid;
- } catch (NameNotFoundException e) {
- Slogf.d(LOG_TAG, "Calling package not found", e);
+ try (var snapshot = mInjector.getPackageManagerLocal().withUnfilteredSnapshot()) {
+ var packageState = snapshot.getPackageStates().get(packageName);
+ var userId = UserHandle.getUserId(callingUid);
+ if (packageState == null) {
+ Slogf.d(LOG_TAG, "Calling UID " + callingUid + " not found");
return false;
+ } else if (!packageState.getUserStateOrDefault(userId).isInstalled()) {
+ Slogf.d(LOG_TAG, "Calling UID " + callingUid + " not installed");
+ return false;
+ } else {
+ return callingUid == UserHandle.getUid(userId, packageState.getAppId());
}
- });
+ }
}
private DevicePolicyConstants loadConstants() {
@@ -22705,11 +22726,24 @@
DEFAULT_KEEP_PROFILES_RUNNING_FLAG);
}
- private static boolean isWorkProfileTelephonyFlagEnabled() {
- return DeviceConfig.getBoolean(
- NAMESPACE_DEVICE_POLICY_MANAGER,
- ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
- DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
+ private boolean isWorkProfileTelephonyEnabled() {
+ return isWorkProfileTelephonyDevicePolicyManagerFlagEnabled()
+ && isWorkProfileTelephonySubscriptionManagerFlagEnabled();
+ }
+
+ private boolean isWorkProfileTelephonyDevicePolicyManagerFlagEnabled() {
+ return DeviceConfig.getBoolean(NAMESPACE_DEVICE_POLICY_MANAGER,
+ ENABLE_WORK_PROFILE_TELEPHONY_FLAG, DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
+ }
+
+ private boolean isWorkProfileTelephonySubscriptionManagerFlagEnabled() {
+ final long ident = mInjector.binderClearCallingIdentity();
+ try {
+ return DeviceConfig.getBoolean(NAMESPACE_TELEPHONY, ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
+ false);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
}
@Override
@@ -22822,7 +22856,7 @@
@Override
public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() {
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
synchronized (getLockObject()) {
ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
@@ -22836,7 +22870,7 @@
@Override
public void setManagedSubscriptionsPolicy(ManagedSubscriptionsPolicy policy) {
- if (!isWorkProfileTelephonyFlagEnabled()) {
+ if (!isWorkProfileTelephonyEnabled()) {
throw new UnsupportedOperationException("This api is not enabled");
}
CallerIdentity caller = getCallerIdentity();
@@ -22844,9 +22878,10 @@
"This policy can only be set by a profile owner on an organization-owned "
+ "device.");
+ int parentUserId = getProfileParentId(caller.getUserId());
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerLocked(caller.getUserId());
- if (hasUserSetupCompleted(UserHandle.USER_SYSTEM) && !isAdminTestOnlyLocked(
+ if (hasUserSetupCompleted(parentUserId) && !isAdminTestOnlyLocked(
admin.info.getComponent(), caller.getUserId())) {
throw new IllegalStateException("Not allowed to apply this policy after setup");
}
@@ -22868,7 +22903,6 @@
if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
final long id = mInjector.binderClearCallingIdentity();
try {
- int parentUserId = getProfileParentId(caller.getUserId());
installOemDefaultDialerAndSmsApp(caller.getUserId());
updateTelephonyCrossProfileIntentFilters(parentUserId, caller.getUserId(), true);
} finally {
@@ -22879,10 +22913,8 @@
private void installOemDefaultDialerAndSmsApp(int targetUserId) {
try {
- String defaultDialerPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultDialer);
- String defaultSmsPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultSms);
+ String defaultDialerPackageName = getOemDefaultDialerPackage();
+ String defaultSmsPackageName = getOemDefaultSmsPackage();
if (defaultDialerPackageName != null) {
mIPackageManager.installExistingPackageAsUser(defaultDialerPackageName,
@@ -22908,6 +22940,15 @@
}
}
+ private String getOemDefaultDialerPackage() {
+ TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+ return telecomManager.getSystemDialerPackage();
+ }
+
+ private String getOemDefaultSmsPackage() {
+ return mContext.getString(R.string.config_defaultSms);
+ }
+
private void updateDialerAndSmsManagedShortcutsOverrideCache(
String defaultDialerPackageName, String defaultSmsPackageName) {
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
index fd31b22..d559b67 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerTests.java
@@ -84,9 +84,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -2904,108 +2901,6 @@
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- private static class TestDexModuleRegisterCallback
- extends PackageManager.DexModuleRegisterCallback {
- private String mDexModulePath = null;
- private boolean mSuccess = false;
- private String mMessage = null;
- CountDownLatch doneSignal = new CountDownLatch(1);
-
- @Override
- public void onDexModuleRegistered(String dexModulePath, boolean success, String message) {
- mDexModulePath = dexModulePath;
- mSuccess = success;
- mMessage = message;
- doneSignal.countDown();
- }
-
- boolean waitTillDone() {
- long startTime = System.currentTimeMillis();
- while (System.currentTimeMillis() - startTime < MAX_WAIT_TIME) {
- try {
- return doneSignal.await(MAX_WAIT_TIME, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- Log.i(TAG, "Interrupted during sleep", e);
- }
- }
- return false;
- }
-
- }
-
- // Verify that the base code path cannot be registered.
- public void testRegisterDexModuleBaseCode() throws Exception {
- PackageManager pm = getPm();
- ApplicationInfo info = getContext().getApplicationInfo();
- TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
- pm.registerDexModule(info.getBaseCodePath(), callback);
- assertTrue(callback.waitTillDone());
- assertEquals(info.getBaseCodePath(), callback.mDexModulePath);
- assertFalse("BaseCodePath should not be registered", callback.mSuccess);
- }
-
- // Verify that modules which are not own by the calling package are not registered.
- public void testRegisterDexModuleNotOwningModule() throws Exception {
- TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
- String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
- getPm().registerDexModule(moduleBelongingToOtherPackage, callback);
- assertTrue(callback.waitTillDone());
- assertEquals(moduleBelongingToOtherPackage, callback.mDexModulePath);
- assertTrue(callback.waitTillDone());
- assertFalse("Only modules belonging to the calling package can be registered",
- callback.mSuccess);
- }
-
- // Verify that modules owned by the package are successfully registered.
- public void testRegisterDexModuleSuccessfully() throws Exception {
- ApplicationInfo info = getContext().getApplicationInfo();
- // Copy the main apk into the data folder and use it as a "module".
- File dexModuleDir = new File(info.dataDir, "module-dir");
- File dexModule = new File(dexModuleDir, "module.apk");
- try {
- assertNotNull(FileUtils.createDir(
- dexModuleDir.getParentFile(), dexModuleDir.getName()));
- Files.copy(Paths.get(info.getBaseCodePath()), dexModule.toPath(),
- StandardCopyOption.REPLACE_EXISTING);
- TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
- getPm().registerDexModule(dexModule.toString(), callback);
- assertTrue(callback.waitTillDone());
- assertEquals(dexModule.toString(), callback.mDexModulePath);
- assertTrue(callback.waitTillDone());
- assertTrue(callback.mMessage, callback.mSuccess);
-
- // NOTE:
- // This actually verifies internal behaviour which might change. It's not
- // ideal but it's the best we can do since there's no other place we can currently
- // write a better test.
- for(String isa : getAppDexInstructionSets(info)) {
- Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.odex"));
- Files.exists(Paths.get(dexModuleDir.toString(), "oat", isa, "module.vdex"));
- }
- } finally {
- FileUtils.deleteContentsAndDir(dexModuleDir);
- }
- }
-
- // If the module does not exist on disk we should get a failure.
- public void testRegisterDexModuleNotExists() throws Exception {
- ApplicationInfo info = getContext().getApplicationInfo();
- String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
- TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
- getPm().registerDexModule(nonExistentApk, callback);
- assertTrue(callback.waitTillDone());
- assertEquals(nonExistentApk, callback.mDexModulePath);
- assertTrue(callback.waitTillDone());
- assertFalse("DexModule registration should fail", callback.mSuccess);
- }
-
- // If the module does not exist on disk we should get a failure.
- public void testRegisterDexModuleNotExistsNoCallback() throws Exception {
- ApplicationInfo info = getContext().getApplicationInfo();
- String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
- getPm().registerDexModule(nonExistentApk, null);
- }
-
@LargeTest
public void testMinInstallableTargetSdkPass() throws Exception {
// Test installing a package that meets the minimum installable sdk requirement
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
index 8715afd..a93e8ad 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
@@ -95,9 +95,13 @@
state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_REJECT);
- assertFalse("Verification should not be marked as complete yet",
+ assertTrue("Verification should be considered complete now",
state.isVerificationComplete());
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+
+ // Nothing changes.
state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_REJECT);
assertTrue("Verification should be considered complete now",
@@ -117,9 +121,13 @@
state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_REJECT);
- assertFalse("Verification should not be marked as complete yet",
+ assertTrue("Verification should be considered complete now",
state.isVerificationComplete());
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+
+ // Nothing changes.
state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_ALLOW);
assertTrue("Verification should be considered complete now",
@@ -151,6 +159,162 @@
state.isInstallAllowed());
}
+ public void testPackageVerificationState_TwoRequiredVerifiers_SecondTimesOut_DefaultAllow() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Timeout with default ALLOW.
+ processOnTimeout(state, PackageManager.VERIFICATION_ALLOW, REQUIRED_UID_2, true);
+ }
+
+ public void testPackageVerificationState_TwoRequiredVerifiers_SecondTimesOut_DefaultReject() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Timeout with default REJECT.
+ processOnTimeout(state, PackageManager.VERIFICATION_REJECT, REQUIRED_UID_2, false);
+ }
+
+ public void testPackageVerificationState_TwoRequiredVerifiers_FirstTimesOut_DefaultAllow() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Timeout with default ALLOW.
+ processOnTimeout(state, PackageManager.VERIFICATION_ALLOW, REQUIRED_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_ALLOW);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertTrue("Installation should be marked as allowed",
+ state.isInstallAllowed());
+ }
+
+ public void testPackageVerificationState_TwoRequiredVerifiers_FirstTimesOut_DefaultReject() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Timeout with default REJECT.
+ processOnTimeout(state, PackageManager.VERIFICATION_REJECT, REQUIRED_UID_1);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+
+ // Nothing changes.
+ state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_ALLOW);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+ }
+
+ public void testPackageVerificationState_TwoRequiredVerifiers_FirstTimesOut_SecondExtends_DefaultAllow() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.extendTimeout(REQUIRED_UID_2);
+
+ // Timeout with default ALLOW.
+ processOnTimeout(state, PackageManager.VERIFICATION_ALLOW, REQUIRED_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ assertTrue("Timeout is extended",
+ state.timeoutExtended(REQUIRED_UID_2));
+
+ state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_ALLOW);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertTrue("Installation should be marked as allowed",
+ state.isInstallAllowed());
+ }
+
+ public void testPackageVerificationState_TwoRequiredVerifiers_FirstTimesOut_SecondExtends_DefaultReject() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+ state.addRequiredVerifierUid(REQUIRED_UID_2);
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.extendTimeout(REQUIRED_UID_2);
+
+ // Timeout with default REJECT.
+ processOnTimeout(state, PackageManager.VERIFICATION_REJECT, REQUIRED_UID_1);
+
+ assertFalse("Timeout should not be extended for this verifier",
+ state.timeoutExtended(REQUIRED_UID_2));
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+
+ // Nothing changes.
+ state.setVerifierResponse(REQUIRED_UID_2, PackageManager.VERIFICATION_ALLOW);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+
+ assertFalse("Installation should be marked as denied",
+ state.isInstallAllowed());
+ }
+
public void testPackageVerificationState_RequiredAndOneSufficient_RequiredDeniedInstall() {
PackageVerificationState state = new PackageVerificationState(null);
state.addRequiredVerifierUid(REQUIRED_UID_1);
@@ -231,6 +395,66 @@
state.isInstallAllowed());
}
+ public void testPackageVerificationState_RequiredAllow_SufficientTimesOut_DefaultAllow() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Required allows.
+ state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
+
+ // Timeout with default ALLOW.
+ processOnTimeout(state, PackageManager.VERIFICATION_ALLOW, REQUIRED_UID_1, true);
+ }
+
+ public void testPackageVerificationState_RequiredExtendAllow_SufficientTimesOut_DefaultAllow() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Extend first.
+ state.extendTimeout(REQUIRED_UID_1);
+
+ // Required allows.
+ state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
+
+ // Timeout with default ALLOW.
+ processOnTimeout(state, PackageManager.VERIFICATION_ALLOW, REQUIRED_UID_1, true);
+ }
+
+ public void testPackageVerificationState_RequiredAllow_SufficientTimesOut_DefaultReject() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.addRequiredVerifierUid(REQUIRED_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ state.addSufficientVerifier(SUFFICIENT_UID_1);
+
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+
+ // Required allows.
+ state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
+
+ // Timeout with default REJECT.
+ processOnTimeout(state, PackageManager.VERIFICATION_REJECT, REQUIRED_UID_1, true);
+ }
+
public void testPackageVerificationState_RequiredAndTwoSufficient_OneSufficientIsEnough() {
PackageVerificationState state = new PackageVerificationState(null);
state.addRequiredVerifierUid(REQUIRED_UID_1);
@@ -400,4 +624,25 @@
assertFalse(state.areAllVerificationsComplete());
}
+
+ private void processOnTimeout(PackageVerificationState state, int code, int uid) {
+ // CHECK_PENDING_VERIFICATION handler.
+ assertFalse("Verification should not be marked as complete yet",
+ state.isVerificationComplete());
+ assertFalse("Timeout should not be extended for this verifier",
+ state.timeoutExtended(uid));
+
+ PackageVerificationResponse response = new PackageVerificationResponse(code, uid);
+ VerificationUtils.processVerificationResponseOnTimeout(-1, state, response, null);
+ }
+
+ private void processOnTimeout(PackageVerificationState state, int code, int uid,
+ boolean expectAllow) {
+ processOnTimeout(state, code, uid);
+
+ assertTrue("Verification should be considered complete now",
+ state.isVerificationComplete());
+ assertEquals("Installation should be marked as " + (expectAllow ? "allowed" : "rejected"),
+ expectAllow, state.isInstallAllowed());
+ }
}
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 80b164d..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-"1.23
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq
deleted file mode 100644
index 582d8c8..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-+2.5
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq
deleted file mode 100644
index dadd973..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
index 573541a..dadd973 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
index 573541a..749fce6 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq
deleted file mode 100644
index dadd973..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
index 573541a..dadd973 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
index 573541a..749fce6 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index f9f5325..a5adf3f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -2778,51 +2778,70 @@
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 1, getNewMockPendingIntent());
}
- final String otherUidPackage1 = "other.uid.package1";
- final String otherUidPackage2 = "other.uid.package2";
- final int otherUid = 1243;
+ final String otherPackage1 = "other.package1";
+ final String otherPackage2 = "other.package2";
+ final int otherAppId = 1243;
+ final int otherUser1 = 31;
+ final int otherUser2 = 8;
+ final int otherUid1 = UserHandle.getUid(otherUser1, otherAppId);
+ final int otherUid2 = UserHandle.getUid(otherUser2, otherAppId);
registerAppIds(
- new String[]{TEST_CALLING_PACKAGE, otherUidPackage1, otherUidPackage2},
- new Integer[]{TEST_CALLING_UID, otherUid, otherUid}
+ new String[]{TEST_CALLING_PACKAGE, otherPackage1, otherPackage2},
+ new Integer[]{UserHandle.getAppId(TEST_CALLING_UID), otherAppId, otherAppId}
);
for (int i = 0; i < 9; i++) {
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 11, 0,
- getNewMockPendingIntent(otherUid, otherUidPackage1), 0, 0, otherUid,
- otherUidPackage1, null);
+ getNewMockPendingIntent(otherUid1, otherPackage1), 0, 0, otherUid1,
+ otherPackage1, null);
}
for (int i = 0; i < 8; i++) {
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 20, 0,
- getNewMockPendingIntent(otherUid, otherUidPackage2), 0, 0, otherUid,
- otherUidPackage2, null);
+ getNewMockPendingIntent(otherUid1, otherPackage2), 0, 0, otherUid1,
+ otherPackage2, null);
}
- assertEquals(27, mService.mAlarmStore.size());
+ for (int i = 0; i < 7; i++) {
+ setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 28, 0,
+ getNewMockPendingIntent(otherUid2, otherPackage2), 0, 0, otherUid2,
+ otherPackage2, null);
+ }
+
+ assertEquals(34, mService.mAlarmStore.size());
try {
- mBinder.removeAll(otherUidPackage1);
+ mBinder.removeAll(otherPackage1);
fail("removeAll() for wrong package did not throw SecurityException");
} catch (SecurityException se) {
// Expected
}
try {
- mBinder.removeAll(otherUidPackage2);
+ mBinder.removeAll(otherPackage2);
fail("removeAll() for wrong package did not throw SecurityException");
} catch (SecurityException se) {
// Expected
}
mBinder.removeAll(TEST_CALLING_PACKAGE);
- assertEquals(17, mService.mAlarmStore.size());
+ assertEquals(24, mService.mAlarmStore.size());
assertEquals(0, mService.mAlarmStore.getCount(a -> a.matches(TEST_CALLING_PACKAGE)));
- mTestCallingUid = otherUid;
- mBinder.removeAll(otherUidPackage1);
- assertEquals(0, mService.mAlarmStore.getCount(a -> a.matches(otherUidPackage1)));
- assertEquals(8, mService.mAlarmStore.getCount(a -> a.matches(otherUidPackage2)));
+ mTestCallingUid = otherUid1;
+ mBinder.removeAll(otherPackage1);
+ assertEquals(15, mService.mAlarmStore.size());
+ assertEquals(15, mService.mAlarmStore.getCount(a -> a.matches(otherPackage2)));
+ assertEquals(0, mService.mAlarmStore.getCount(a -> a.matches(otherPackage1)));
+
+ mBinder.removeAll(otherPackage2);
+ assertEquals(7, mService.mAlarmStore.size());
+ assertEquals(7, mService.mAlarmStore.getCount(a -> a.matches(otherPackage2)));
+
+ mTestCallingUid = otherUid2;
+ mBinder.removeAll(otherPackage2);
+ assertEquals(0, mService.mAlarmStore.size());
}
@Test
@@ -3856,4 +3875,52 @@
assertAndHandleMessageSync(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED);
assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
}
+
+ @Test
+ public void lookForPackageLocked() throws Exception {
+ final String package2 = "test.package.2";
+ final int uid2 = 359712;
+ setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 10, getNewMockPendingIntent());
+ setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 15,
+ getNewMockPendingIntent(uid2, package2));
+
+ doReturn(true).when(mService).checkAllowNonWakeupDelayLocked(anyLong());
+
+ assertTrue(mService.lookForPackageLocked(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ assertTrue(mService.lookForPackageLocked(package2, uid2));
+
+ mNowElapsedTest += 10; // Advance time past the first alarm only.
+ mTestTimer.expire();
+
+ assertTrue(mService.lookForPackageLocked(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ assertTrue(mService.lookForPackageLocked(package2, uid2));
+
+ // The non-wakeup alarm is sent on interactive state change: false -> true.
+ mService.interactiveStateChangedLocked(false);
+ mService.interactiveStateChangedLocked(true);
+
+ assertFalse(mService.lookForPackageLocked(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ assertTrue(mService.lookForPackageLocked(package2, uid2));
+
+ mNowElapsedTest += 10; // Advance time past the second alarm.
+ mTestTimer.expire();
+
+ assertFalse(mService.lookForPackageLocked(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ assertFalse(mService.lookForPackageLocked(package2, uid2));
+ }
+
+ @Test
+ public void onQueryPackageRestart() {
+ final String[] packages = {"p1", "p2", "p3"};
+ final int uid = 5421;
+ final Intent packageAdded = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART)
+ .setData(Uri.fromParts("package", packages[0], null))
+ .putExtra(Intent.EXTRA_PACKAGES, packages)
+ .putExtra(Intent.EXTRA_UID, uid);
+ mPackageChangesReceiver.onReceive(mMockContext, packageAdded);
+
+ for (String p : packages) {
+ verify(mService).lookForPackageLocked(p, uid);
+ }
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
index a129f39..246b0f04 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
@@ -210,4 +210,26 @@
createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)));
assertTrue("Alarm clock not exempt", isExemptFromTare(createAlarmClock(anything)));
}
+
+ @Test
+ public void snapshotImmutable() {
+ final Alarm a = createDefaultAlarm(0, 0, 0);
+
+ final Random random = new Random(234);
+ final long[] policyElapsed = new long[NUM_POLICIES];
+ for (int i = 0; i < NUM_POLICIES; i++) {
+ a.setPolicyElapsed(i, policyElapsed[i] = random.nextInt(1 << 10));
+ }
+
+ final Alarm.Snapshot snapshot = new Alarm.Snapshot(a);
+
+ for (int i = 0; i < NUM_POLICIES; i++) {
+ assertEquals(policyElapsed[i], snapshot.mPolicyWhenElapsed[i]);
+ }
+
+ for (int i = 0; i < NUM_POLICIES; i++) {
+ a.setPolicyElapsed(i, policyElapsed[i] + 5 + i);
+ assertEquals(policyElapsed[i], snapshot.mPolicyWhenElapsed[i]);
+ }
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index 63e8e56..390119c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -52,6 +52,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -355,6 +356,33 @@
}
/**
+ * Queue with a "normal" and "deferrable" broadcast is runnable at different times depending
+ * on process cached state; when cached it's delayed indefinitely.
+ */
+ @Test
+ public void testRunnableAt_Normal_Deferrable() {
+ final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+ PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
+
+ final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ final BroadcastOptions options = BroadcastOptions.makeBasic()
+ .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
+ final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, options,
+ List.of(makeMockRegisteredReceiver()), false);
+ queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);
+
+ queue.setProcessCached(false);
+ final long notCachedRunnableAt = queue.getRunnableAt();
+ queue.setProcessCached(true);
+ final long cachedRunnableAt = queue.getRunnableAt();
+ assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
+ assertFalse(queue.isRunnable());
+ assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER,
+ queue.getRunnableAtReason());
+ assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
+ }
+
+ /**
* Queue with a "normal" broadcast is runnable at different times depending
* on process cached state; when cached it's delayed by some amount.
*/
@@ -364,8 +392,10 @@
PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane,
- List.of(makeMockRegisteredReceiver()));
+ final BroadcastOptions options = BroadcastOptions.makeBasic()
+ .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
+ final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane, options,
+ List.of(makeMockRegisteredReceiver()), false);
queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);
queue.setProcessCached(false);
@@ -373,6 +403,8 @@
queue.setProcessCached(true);
final long cachedRunnableAt = queue.getRunnableAt();
assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
+ assertTrue(queue.isRunnable());
+ assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason());
assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked());
}
@@ -519,11 +551,13 @@
}
@Test
- public void testRunnableAt_Cached_Prioritized() {
+ public void testRunnableAt_Cached_Prioritized_NonDeferrable() {
final List receivers = List.of(
withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10),
withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10));
- doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null,
+ final BroadcastOptions options = BroadcastOptions.makeBasic()
+ .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE);
+ doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options,
receivers, null, false), REASON_CONTAINS_PRIORITIZED);
}
@@ -1079,7 +1113,8 @@
eq(getUidForPackage(PACKAGE_GREEN)), anyInt(), eq(Intent.ACTION_TIME_TICK),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD),
- anyLong(), anyLong(), anyLong(), anyInt(), anyString(), anyString()), times(1));
+ anyLong(), anyLong(), anyLong(), anyInt(), nullable(String.class), anyString()),
+ times(1));
}
private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index f86e464..44ec26e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -19,9 +19,11 @@
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL;
+import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_READ_SMS;
import static android.app.AppOpsManager.OP_WIFI_SCAN;
import static android.app.AppOpsManager.OP_WRITE_SMS;
+import static android.os.UserHandle.getUserId;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -33,12 +35,15 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
+import android.app.AppOpsManager;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
import android.content.ContentResolver;
@@ -48,14 +53,19 @@
import android.os.HandlerThread;
import android.os.Process;
import android.provider.Settings;
+import android.util.ArrayMap;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
+import com.android.server.pm.PackageManagerLocal;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import org.junit.After;
@@ -67,6 +77,7 @@
import java.io.File;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
@@ -133,6 +144,7 @@
mMockingSession = mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(LocalServices.class)
+ .spyStatic(LocalManagerRegistry.class)
.spyStatic(Settings.Global.class)
.startMocking();
@@ -152,6 +164,23 @@
doReturn(mockPackageManagerInternal).when(
() -> LocalServices.getService(PackageManagerInternal.class));
+ PackageManagerLocal mockPackageManagerLocal = mock(PackageManagerLocal.class);
+ PackageManagerLocal.UnfilteredSnapshot mockUnfilteredSnapshot =
+ mock(PackageManagerLocal.UnfilteredSnapshot.class);
+ PackageState mockMyPS = mock(PackageState.class);
+ ArrayMap<String, PackageState> packageStates = new ArrayMap<>();
+ packageStates.put(sMyPackageName, mockMyPS);
+ when(mockMyPS.getAppId()).thenReturn(mMyUid);
+ when(mockUnfilteredSnapshot.getPackageStates()).thenReturn(packageStates);
+ when(mockPackageManagerLocal.withUnfilteredSnapshot()).thenReturn(mockUnfilteredSnapshot);
+ doReturn(mockPackageManagerLocal).when(
+ () -> LocalManagerRegistry.getManager(PackageManagerLocal.class));
+
+ UserManagerInternal mockUserManagerInternal = mock(UserManagerInternal.class);
+ when(mockUserManagerInternal.getUserIds()).thenReturn(new int[] {getUserId(mMyUid)});
+ doReturn(mockUserManagerInternal).when(
+ () -> LocalServices.getService(UserManagerInternal.class));
+
// Mock behavior to use specific Settings.Global.APPOP_HISTORY_PARAMETERS
doReturn(null).when(() -> Settings.Global.getString(any(ContentResolver.class),
eq(Settings.Global.APPOP_HISTORY_PARAMETERS)));
@@ -337,6 +366,25 @@
assertThat(getLoggedOps()).isNull();
}
+ @Test
+ public void testUidStateInitializationDoesntClearState() throws InterruptedException {
+ mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
+ mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ mAppOpsService.initializeUidStates();
+ List<PackageOps> ops = mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName,
+ new int[]{OP_READ_SMS});
+ assertNotNull(ops);
+ for (int i = 0; i < ops.size(); i++) {
+ List<OpEntry> opEntries = ops.get(i).getOps();
+ for (int j = 0; j < opEntries.size(); j++) {
+ Map<String, AppOpsManager.AttributedOpEntry> attributedOpEntries = opEntries.get(
+ j).getAttributedOpEntries();
+ assertNotEquals(-1, attributedOpEntries.get(null)
+ .getLastAccessTime(OP_FLAG_SELF));
+ }
+ }
+ }
+
private List<PackageOps> getLoggedOps() {
return mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName, null /* all ops */);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 51dcc03..0ab984b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -21,11 +21,14 @@
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -672,6 +675,7 @@
@Test
public void testStopScreenOffBrightnessSensorControllerWhenDisplayDeviceChanges() {
+ // New display device
setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
@@ -711,6 +715,56 @@
verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
}
+ @Test
+ public void testShortTermModelPersistsWhenDisplayDeviceChanges() {
+ float lux = 2000;
+ float brightness = 0.4f;
+ float nits = 500;
+ when(mHolder.brightnessMappingStrategy.getUserLux()).thenReturn(lux);
+ when(mHolder.brightnessMappingStrategy.getUserBrightness()).thenReturn(brightness);
+ when(mHolder.brightnessMappingStrategy.convertToNits(brightness)).thenReturn(nits);
+ when(mHolder.brightnessMappingStrategy.convertToFloatScale(nits)).thenReturn(brightness);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1);
+ clearInvocations(mHolder.injector);
+
+ // New display device
+ setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+ mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+ advanceTime(1);
+
+ verify(mHolder.injector).getAutomaticBrightnessController(
+ any(AutomaticBrightnessController.Callbacks.class),
+ any(Looper.class),
+ eq(mSensorManagerMock),
+ any(),
+ eq(mHolder.brightnessMappingStrategy),
+ anyInt(),
+ anyFloat(),
+ anyFloat(),
+ anyFloat(),
+ anyInt(),
+ anyInt(),
+ anyLong(),
+ anyLong(),
+ anyBoolean(),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ eq(mContextSpy),
+ any(HighBrightnessModeController.class),
+ any(BrightnessThrottler.class),
+ isNull(),
+ anyInt(),
+ anyInt(),
+ eq(lux),
+ eq(brightness)
+ );
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
@@ -796,9 +850,9 @@
final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
mock(ScreenOffBrightnessSensorController.class);
- TestInjector injector = new TestInjector(displayPowerState, animator,
+ TestInjector injector = spy(new TestInjector(displayPowerState, animator,
automaticBrightnessController, wakelockController, brightnessMappingStrategy,
- hysteresisLevels, screenOffBrightnessSensorController);
+ hysteresisLevels, screenOffBrightnessSensorController));
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -816,7 +870,8 @@
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, wakelockController,
- screenOffBrightnessSensorController, hbmMetadata);
+ screenOffBrightnessSensorController, hbmMetadata, brightnessMappingStrategy,
+ injector);
}
/**
@@ -833,6 +888,8 @@
public final WakelockController wakelockController;
public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
public final HighBrightnessModeMetadata hbmMetadata;
+ public final BrightnessMappingStrategy brightnessMappingStrategy;
+ public final DisplayPowerController2.Injector injector;
DisplayPowerControllerHolder(DisplayPowerController2 dpc, LogicalDisplay display,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
@@ -840,7 +897,9 @@
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
- HighBrightnessModeMetadata hbmMetadata) {
+ HighBrightnessModeMetadata hbmMetadata,
+ BrightnessMappingStrategy brightnessMappingStrategy,
+ DisplayPowerController2.Injector injector) {
this.dpc = dpc;
this.display = display;
this.displayPowerState = displayPowerState;
@@ -850,6 +909,8 @@
this.wakelockController = wakelockController;
this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
this.hbmMetadata = hbmMetadata;
+ this.brightnessMappingStrategy = brightnessMappingStrategy;
+ this.injector = injector;
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 0a1bf1c..c021ef6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -21,11 +21,14 @@
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -676,6 +679,7 @@
@Test
public void testStopScreenOffBrightnessSensorControllerWhenDisplayDeviceChanges() {
+ // New display device
setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
@@ -715,6 +719,56 @@
verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
}
+ @Test
+ public void testShortTermModelPersistsWhenDisplayDeviceChanges() {
+ float lux = 2000;
+ float brightness = 0.4f;
+ float nits = 500;
+ when(mHolder.brightnessMappingStrategy.getUserLux()).thenReturn(lux);
+ when(mHolder.brightnessMappingStrategy.getUserBrightness()).thenReturn(brightness);
+ when(mHolder.brightnessMappingStrategy.convertToNits(brightness)).thenReturn(nits);
+ when(mHolder.brightnessMappingStrategy.convertToFloatScale(nits)).thenReturn(brightness);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1);
+ clearInvocations(mHolder.injector);
+
+ // New display device
+ setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+ mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+ advanceTime(1);
+
+ verify(mHolder.injector).getAutomaticBrightnessController(
+ any(AutomaticBrightnessController.Callbacks.class),
+ any(Looper.class),
+ eq(mSensorManagerMock),
+ any(),
+ eq(mHolder.brightnessMappingStrategy),
+ anyInt(),
+ anyFloat(),
+ anyFloat(),
+ anyFloat(),
+ anyInt(),
+ anyInt(),
+ anyLong(),
+ anyLong(),
+ anyBoolean(),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ any(HysteresisLevels.class),
+ eq(mContextSpy),
+ any(HighBrightnessModeController.class),
+ any(BrightnessThrottler.class),
+ isNull(),
+ anyInt(),
+ anyInt(),
+ eq(lux),
+ eq(brightness)
+ );
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
@@ -799,9 +853,9 @@
final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
mock(ScreenOffBrightnessSensorController.class);
- DisplayPowerController.Injector injector = new TestInjector(displayPowerState, animator,
+ DisplayPowerController.Injector injector = spy(new TestInjector(displayPowerState, animator,
automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels,
- screenOffBrightnessSensorController);
+ screenOffBrightnessSensorController));
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -819,7 +873,7 @@
return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting,
animator, automaticBrightnessController, screenOffBrightnessSensorController,
- hbmMetadata);
+ hbmMetadata, brightnessMappingStrategy, injector);
}
/**
@@ -835,13 +889,17 @@
public final AutomaticBrightnessController automaticBrightnessController;
public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
public final HighBrightnessModeMetadata hbmMetadata;
+ public final BrightnessMappingStrategy brightnessMappingStrategy;
+ public final DisplayPowerController.Injector injector;
DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
- HighBrightnessModeMetadata hbmMetadata) {
+ HighBrightnessModeMetadata hbmMetadata,
+ BrightnessMappingStrategy brightnessMappingStrategy,
+ DisplayPowerController.Injector injector) {
this.dpc = dpc;
this.display = display;
this.displayPowerState = displayPowerState;
@@ -850,6 +908,8 @@
this.automaticBrightnessController = automaticBrightnessController;
this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
this.hbmMetadata = hbmMetadata;
+ this.brightnessMappingStrategy = brightnessMappingStrategy;
+ this.injector = injector;
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
index d5aa7fe..9a7ee4d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundDexOptServiceUnitTest.java
@@ -47,6 +47,7 @@
import android.os.HandlerThread;
import android.os.PowerManager;
import android.os.Process;
+import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.util.IndentingPrintWriter;
@@ -56,6 +57,7 @@
import com.android.server.pm.dex.DexoptOptions;
import org.junit.After;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -126,6 +128,10 @@
@Before
public void setUp() throws Exception {
+ // These tests are only applicable to the legacy BackgroundDexOptService and cannot be run
+ // when ART Service is enabled.
+ Assume.assumeFalse(SystemProperties.getBoolean("dalvik.vm.useartservice", false));
+
when(mInjector.getCallingUid()).thenReturn(Process.FIRST_APPLICATION_UID);
when(mInjector.getContext()).thenReturn(mContext);
when(mInjector.getDexOptHelper()).thenReturn(mDexOptHelper);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
index 70b5ac0..386fd3e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
@@ -674,13 +674,13 @@
}
protected void expectDisplayAssignedToUser(@UserIdInt int userId, int displayId) {
- expectWithMessage("getDisplayAssignedToUser(%s)", userId)
- .that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(displayId);
+ expectWithMessage("getMainDisplayAssignedToUser(%s)", userId)
+ .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(displayId);
}
protected void expectNoDisplayAssignedToUser(@UserIdInt int userId) {
- expectWithMessage("getDisplayAssignedToUser(%s)", userId)
- .that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
+ expectWithMessage("getMainDisplayAssignedToUser(%s)", userId)
+ .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
}
protected void expectDisplaysAssignedToUserContainsDisplayId(
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java
index 84a61c7..a9b68eb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java
@@ -136,17 +136,30 @@
mEconomicPolicy.getMinSatiatedConsumptionLimit());
assertEquals(EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
mEconomicPolicy.getMaxSatiatedConsumptionLimit());
+
final String pkgRestricted = "com.pkg.restricted";
when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
+ assertEquals(0, mEconomicPolicy.getMinSatiatedBalance(0, pkgRestricted));
assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
- assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
- mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
+
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
+ mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
+
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
+ mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
+ assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
+ mEconomicPolicy.getMaxSatiatedBalance(0, pkgHeadlessSystemApp));
+
assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
+ assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
+ mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
}
@Test
@@ -156,6 +169,8 @@
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(25));
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(10));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(9));
+ setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(8));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(7));
assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
@@ -168,6 +183,9 @@
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(9), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(arcToCake(8), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(7), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}
@@ -179,6 +197,8 @@
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(-5));
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(-1));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(-2));
+ setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(-3));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(-3));
assertEquals(arcToCake(1), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
@@ -191,6 +211,9 @@
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
// Test min+max reversed.
@@ -199,6 +222,8 @@
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(3));
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(10));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(11));
+ setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(12));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(13));
assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
@@ -207,6 +232,7 @@
assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
assertEquals(arcToCake(13), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java
index cad608f..d66e74a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java
@@ -189,6 +189,10 @@
setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(11));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(8));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(5));
+ setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(6));
+ setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(4));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(3));
setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(2));
@@ -202,6 +206,9 @@
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(arcToCake(10), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java
index ebf760c..22c7310 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java
@@ -149,6 +149,13 @@
assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
+ mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
+ assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
+ mEconomicPolicy.getMaxSatiatedBalance(0, pkgHeadlessSystemApp));
+
final String pkgUpdater = "com.pkg.updater";
when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(5);
assertEquals(5 * EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES
@@ -177,6 +184,8 @@
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(25));
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(10));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(6));
+ setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(5));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(4));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
arcToCake(1));
@@ -191,6 +200,9 @@
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(6), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(4), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
final String pkgUpdater = "com.pkg.updater";
when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(3);
@@ -206,6 +218,8 @@
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(-5));
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(-1));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(-2));
+ setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(-3));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(-3));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
arcToCake(-4));
@@ -220,6 +234,9 @@
final String pkgExempted = "com.pkg.exempted";
when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
+ when(mIrs.isHeadlessSystemApp(eq(pkgHeadlessSystemApp))).thenReturn(true);
+ assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
final String pkgUpdater = "com.pkg.updater";
when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(5);
@@ -232,6 +249,8 @@
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(3));
setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(10));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(11));
+ setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
+ arcToCake(12));
setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(13));
assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
@@ -240,6 +259,7 @@
assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
assertEquals(arcToCake(13), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
+ assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 24b003c..caa2e36 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -18,6 +18,7 @@
import static android.database.sqlite.SQLiteDatabase.deleteDatabase;
+import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -719,6 +720,41 @@
}
@SmallTest
+ public void testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()
+ throws Exception {
+ unlockSystemUser();
+ ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = new ActivityInfo();
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
+ when(mMockPackageManager.resolveActivityAsUser(
+ any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
+ when(mMockPackageManager.checkSignatures(
+ anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ Response response = new Response(latch, mMockAccountManagerResponse);
+ Bundle options = createOptionsWithAccountName(
+ AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
+ options.putInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, prohibitedFlags);
+
+ mAms.startAddAccountSession(
+ response, // response
+ AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
+ "authTokenType",
+ null, // requiredFeatures
+ true, // expectActivityLaunch
+ options); // optionsIn
+ waitForLatch(latch);
+
+ verify(mMockAccountManagerResponse).onError(
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), contains("invalid intent"));
+ }
+
+ @SmallTest
public void testStartAddAccountSessionError() throws Exception {
unlockSystemUser();
Bundle options = createOptionsWithAccountName(
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
index 73f30d9..b98a6a8 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
@@ -17,9 +17,6 @@
import android.accounts.Account;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Constants shared between test AccountAuthenticators and AccountManagerServiceTest.
*/
@@ -31,6 +28,8 @@
"account_manager_service_test:account_status_token_key";
public static final String KEY_ACCOUNT_PASSWORD =
"account_manager_service_test:account_password_key";
+ public static final String KEY_INTENT_FLAGS =
+ "account_manager_service_test:intent_flags_key";
public static final String KEY_OPTIONS_BUNDLE =
"account_manager_service_test:option_bundle_key";
public static final String ACCOUNT_NAME_SUCCESS = "success_on_return@fixture.com";
diff --git a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
index 8106364..924443e 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
@@ -24,8 +24,6 @@
import android.content.Intent;
import android.os.Bundle;
-import com.android.frameworks.servicestests.R;
-
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -270,11 +268,13 @@
String accountName = null;
Bundle sessionBundle = null;
String password = null;
+ int intentFlags = 0;
if (options != null) {
accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME);
sessionBundle = options.getBundle(
AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE);
password = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD);
+ intentFlags = options.getInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, 0);
}
Bundle result = new Bundle();
@@ -302,6 +302,7 @@
intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT,
eventualActivityResultData);
intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response);
+ intent.setFlags(intentFlags);
result.putParcelable(AccountManager.KEY_INTENT, intent);
} else {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 7d6110e..168642e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -65,7 +65,6 @@
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
-import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Binder;
@@ -145,8 +144,6 @@
@Mock
private ISessionListener mSessionListener;
@Mock
- private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- @Mock
private AuthSessionCoordinator mAuthSessionCoordinator;
BiometricContextProvider mBiometricContextProvider;
@@ -184,9 +181,8 @@
when(mWindowManager.getDefaultDisplay()).thenReturn(
new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS));
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
mBiometricContextProvider = new BiometricContextProvider(mContext, mWindowManager,
- mAmbientDisplayConfiguration, mStatusBarService, null /* handler */,
+ mStatusBarService, null /* handler */,
mAuthSessionCoordinator);
when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
index 2ccdda8..e4aed97 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
@@ -34,7 +34,6 @@
import android.hardware.biometrics.IBiometricContextListener.FoldState;
import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.common.OperationReason;
-import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.DisplayManagerGlobal;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -77,8 +76,6 @@
@Mock
private ISessionListener mSessionListener;
@Mock
- private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- @Mock
private WindowManager mWindowManager;
private OperationContextExt mOpContext = new OperationContextExt();
@@ -87,12 +84,11 @@
@Before
public void setup() throws RemoteException {
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mWindowManager.getDefaultDisplay()).thenReturn(
new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS));
mProvider = new BiometricContextProvider(mContext, mWindowManager,
- mAmbientDisplayConfiguration, mStatusBarService, null /* handler */,
+ mStatusBarService, null /* handler */,
null /* authSessionCoordinator */);
ArgumentCaptor<IBiometricContextListener> captor =
ArgumentCaptor.forClass(IBiometricContextListener.class);
@@ -106,27 +102,21 @@
@Test
public void testIsAod() throws RemoteException {
- mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
+ mListener.onDozeChanged(true /* isAod */, false /* isAwake */);
assertThat(mProvider.isAod()).isTrue();
- mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
- assertThat(mProvider.isAod()).isFalse();
-
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
- mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
- assertThat(mProvider.isAod()).isFalse();
- mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
+ mListener.onDozeChanged(false /* isAod */, false /* isAwake */);
assertThat(mProvider.isAod()).isFalse();
}
@Test
public void testIsAwake() throws RemoteException {
- mListener.onDozeChanged(false /* isDozing */, true /* isAwake */);
+ mListener.onDozeChanged(false /* isAod */, true /* isAwake */);
assertThat(mProvider.isAwake()).isTrue();
- mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
+ mListener.onDozeChanged(false /* isAod */, false /* isAwake */);
assertThat(mProvider.isAwake()).isFalse();
- mListener.onDozeChanged(true /* isDozing */, true /* isAwake */);
+ mListener.onDozeChanged(true /* isAod */, true /* isAwake */);
assertThat(mProvider.isAwake()).isTrue();
- mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
+ mListener.onDozeChanged(true /* isAod */, false /* isAwake */);
assertThat(mProvider.isAwake()).isFalse();
}
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 f0013a6..9b32a80 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -56,6 +56,7 @@
import com.android.server.LocalServices;
import com.android.server.PersistentDataBlockManagerInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -150,6 +151,11 @@
}
@Override
+ PackageManagerLocal getPackageManagerLocal() {
+ return services.packageManagerLocal;
+ }
+
+ @Override
PowerManagerInternal getPowerManagerInternal() {
return services.powerManagerInternal;
}
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 aaabb28..dd81abe 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1398,8 +1398,8 @@
when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle());
// Now call clear.
- doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager).
- getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
+ getServices().addTestPackageUid(admin1.getPackageName(),
+ DpmMockContext.CALLER_SYSTEM_USER_UID);
// But first pretend the user is locked. Then it should fail.
when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(false);
@@ -1495,9 +1495,7 @@
mContext.binder.callingUid = DpmMockContext.CALLER_UID;
// Now call clear.
- doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManager).getPackageUidAsUser(
- eq(admin1.getPackageName()),
- anyInt());
+ getServices().addTestPackageUid(admin1.getPackageName(), DpmMockContext.CALLER_UID);
assertExpectException(SecurityException.class,
/* messageRegex =*/ "clearDeviceOwner can only be called by the device owner",
() -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
@@ -1734,9 +1732,7 @@
eq(userId));
doReturn(true).when(getServices().ipackageManager).isPackageAvailable(packageName, userId);
// Setup application UID with the PackageManager
- doReturn(uid).when(getServices().packageManager).getPackageUidAsUser(
- eq(packageName),
- eq(userId));
+ getServices().addTestPackageUid(packageName, uid);
// Associate packageName to uid
doReturn(packageName).when(getServices().ipackageManager).getNameForUid(eq(uid));
doReturn(new String[]{packageName})
@@ -3955,9 +3951,9 @@
assertThat(dpms.hasUserSetupCompleted()).isFalse();
}
- private void clearDeviceOwner() throws Exception {
- doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager)
- .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
+ private void clearDeviceOwner() {
+ getServices().addTestPackageUid(admin1.getPackageName(),
+ DpmMockContext.CALLER_SYSTEM_USER_UID);
mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
runAsCaller(mAdmin1Context, dpms, dpm -> {
@@ -5002,6 +4998,8 @@
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "true", false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "true", false);
// Even if the caller is the managed profile, the current user is the user 0
when(getServices().iactivityManager.getCurrentUser())
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
@@ -5064,6 +5062,8 @@
verify(getServices().subscriptionManager).setSubscriptionUserHandle(0, null);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "false", false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "false", false);
}
@Test
@@ -6317,7 +6317,7 @@
mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID;
setAsProfileOwner(admin1);
- final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext);
+ var caller = new DpmMockContext(getServices(), mRealTestContext);
caller.packageName = "com.example.delegate";
caller.binder.callingUid = setupPackageInPackageManager(caller.packageName,
CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE);
@@ -6961,6 +6961,7 @@
@Test
public void testIsPackageAllowedToAccessCalendar_adminNotAllowed() {
+ final String testPackage = "TEST_PACKAGE";
setAsProfileOwner(admin1);
dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet());
when(getServices().settings.settingsSecureGetIntForUser(
@@ -6968,7 +6969,7 @@
0, CALLER_USER_HANDLE)).thenReturn(1);
mContext.permissions.add(permission.INTERACT_ACROSS_USERS);
- assertThat(dpm.isPackageAllowedToAccessCalendar("TEST_PACKAGE")).isFalse();
+ assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isFalse();
}
@Test
@@ -6987,6 +6988,7 @@
@Test
public void testIsPackageAllowedToAccessCalendar_bothAllowed() {
final String testPackage = "TEST_PACKAGE";
+ getServices().addTestPackageUid(testPackage, DpmMockContext.ANOTHER_UID);
setAsProfileOwner(admin1);
dpm.setCrossProfileCalendarPackages(admin1, null);
when(getServices().settings.settingsSecureGetIntForUser(
@@ -7000,24 +7002,22 @@
@Test
public void testIsPackageAllowedToAccessCalendar_requiresPermission() {
final String testPackage = "TEST_PACKAGE";
+ getServices().addTestPackageUid(testPackage, DpmMockContext.ANOTHER_UID);
assertExpectException(SecurityException.class, /* messageRegex= */ null,
() -> dpm.isPackageAllowedToAccessCalendar(testPackage));
}
@Test
- public void testIsPackageAllowedToAccessCalendar_samePackageAndSameUser_noPermissionRequired()
- throws Exception {
+ public void testIsPackageAllowedToAccessCalendar_samePackageAndSameUser_noPermissionRequired() {
final String testPackage = "TEST_PACKAGE";
setAsProfileOwner(admin1);
dpm.setCrossProfileCalendarPackages(admin1, null);
when(getServices().settings.settingsSecureGetIntForUser(
Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
0, CALLER_USER_HANDLE)).thenReturn(1);
- doReturn(mContext.binder.callingUid)
- .when(getServices().packageManager).getPackageUidAsUser(
- eq(testPackage),
- anyInt());
+
+ getServices().addTestPackageUid(testPackage, mContext.binder.callingUid);
assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index ded8ad5..9ff600a 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -171,10 +171,15 @@
public ApplicationInfo applicationInfo = null;
public DpmMockContext(MockSystemServices mockSystemServices, Context context) {
+ this(mockSystemServices, context, new MockBinder());
+ }
+
+ public DpmMockContext(MockSystemServices mockSystemServices, Context context,
+ @NonNull MockBinder mockBinder) {
mMockSystemServices = mockSystemServices;
realTestContext = context;
+ binder = mockBinder;
- binder = new MockBinder();
resources = mock(Resources.class);
spiedContext = mock(Context.class);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index b8824c3..03aaeb7e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -67,8 +67,9 @@
@Before
public void setFixtures() throws Exception {
- mServices = new MockSystemServices(mRealTestContext, "test-data");
- mMockContext = new DpmMockContext(mServices, mRealTestContext);
+ var mockBinder = new DpmMockContext.MockBinder();
+ mServices = new MockSystemServices(mRealTestContext, "test-data", mockBinder);
+ mMockContext = new DpmMockContext(mServices, mRealTestContext, mockBinder);
admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
@@ -150,7 +151,7 @@
doReturn(pi).when(mServices.ipackageManager).getPackageInfo(packageName, 0, userId);
- doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(packageName, userId);
+ mServices.addTestPackageUid(packageName, ai.uid);
}
protected void markDelegatedCertInstallerAsInstalled() throws Exception {
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 4163f33..16fdfb1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -25,6 +25,7 @@
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.annotation.NonNull;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -55,6 +56,7 @@
import android.net.Uri;
import android.net.VpnManager;
import android.net.wifi.WifiManager;
+import android.os.Binder;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
@@ -77,7 +79,10 @@
import com.android.server.AlarmManagerInternal;
import com.android.server.PersistentDataBlockManagerInternal;
import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.UserManagerInternal;
+import com.android.server.pm.pkg.PackageState;
+import com.android.server.pm.pkg.PackageUserState;
import com.android.server.wm.ActivityTaskManagerInternal;
import java.io.File;
@@ -101,6 +106,7 @@
public final UsageStatsManagerInternal usageStatsManagerInternal;
public final NetworkPolicyManagerInternal networkPolicyManagerInternal;
public final PackageManagerInternal packageManagerInternal;
+ public final PackageManagerLocal packageManagerLocal;
public final UserManagerForMock userManagerForMock;
public final PowerManagerForMock powerManager;
public final PowerManagerInternal powerManagerInternal;
@@ -143,7 +149,10 @@
public final File dataDir;
public final PolicyPathProvider pathProvider;
- public MockSystemServices(Context realContext, String name) {
+ private final Map<String, PackageState> mTestPackageStates = new ArrayMap<>();
+
+ public MockSystemServices(Context realContext, String name,
+ @NonNull DpmMockContext.MockBinder mockBinder) {
dataDir = new File(realContext.getCacheDir(), name);
DpmTestUtils.clearDir(dataDir);
@@ -157,6 +166,7 @@
userManagerForMock = mock(UserManagerForMock.class);
packageManagerInternal = mock(PackageManagerInternal.class);
+ packageManagerLocal = mock(PackageManagerLocal.class);
powerManager = mock(PowerManagerForMock.class);
powerManagerInternal = mock(PowerManagerInternal.class);
recoverySystem = mock(RecoverySystemForMock.class);
@@ -197,6 +207,14 @@
when(packageManagerInternal.getSystemUiServiceComponent()).thenReturn(
new ComponentName("com.android.systemui", ".Service"));
+ addTestPackageUid("android", DpmMockContext.SYSTEM_UID);
+ addTestPackageUid(realContext.getPackageName(), Binder.getCallingUid());
+ when(packageManagerLocal.withUnfilteredSnapshot()).thenAnswer(unused -> {
+ var snapshot = mock(PackageManagerLocal.UnfilteredSnapshot.class);
+ when(snapshot.getPackageStates()).thenAnswer(unused1 -> mTestPackageStates);
+ return snapshot;
+ });
+
contentResolver = new MockContentResolver();
contentResolver.addProvider("telephony", new MockContentProvider(realContext) {
@Override
@@ -409,6 +427,16 @@
throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
}
+ public void addTestPackageUid(@NonNull String packageName, int uid) {
+ var packageState = mock(PackageState.class);
+ when(packageState.getAppId()).thenReturn(UserHandle.getAppId(uid));
+ when(packageState.getUserStateOrDefault(anyInt())).thenAnswer(invocation -> {
+ var userState = mock(PackageUserState.class);
+ when(userState.isInstalled()).thenReturn(true);
+ return userState;
+ });
+ mTestPackageStates.put(packageName, packageState);
+ }
public static class EnvironmentForMock {
public File getUserSystemDirectory(int userId) {
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 94d30bb..6d2ce7f 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -34,7 +34,9 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -65,12 +67,14 @@
import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
+import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.MessageQueue;
import android.os.Process;
+import android.os.RemoteException;
import android.view.ContentRecordingSession;
import android.view.Display;
import android.view.DisplayCutout;
@@ -1024,11 +1028,14 @@
}
@Test
- public void testCreateVirtualDisplay_setContentRecordingSessionSuccess() throws Exception {
+ public void testCreateVirtualDisplay_setContentRecordingSessionSuccess()
+ throws RemoteException {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
when(mMockWindowManagerInternal
.setContentRecordingSession(any(ContentRecordingSession.class)))
.thenReturn(true);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
@@ -1042,17 +1049,19 @@
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
final int displayId = binderService.createVirtualDisplay(builder.build(),
- mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
}
@Test
- public void testCreateVirtualDisplay_setContentRecordingSessionFail() throws Exception {
+ public void testCreateVirtualDisplay_setContentRecordingSessionFail() throws RemoteException {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
when(mMockWindowManagerInternal
.setContentRecordingSession(any(ContentRecordingSession.class)))
.thenReturn(false);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
@@ -1066,11 +1075,96 @@
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
final int displayId = binderService.createVirtualDisplay(builder.build(),
- mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
assertThat(displayId).isEqualTo(Display.INVALID_DISPLAY);
}
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noFlags() {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ // Set no flags for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+
+ // VirtualDisplay is created but not for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, never()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noMirroringFlag() {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ // Set a non-mirroring flag for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setFlags(VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+
+ // VirtualDisplay is created but not for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, never()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_projection_noMirroringFlag()
+ throws RemoteException {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ when(mMockWindowManagerInternal
+ .setContentRecordingSession(any(ContentRecordingSession.class)))
+ .thenReturn(true);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
+
+ // Set no flags for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a non-null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
+
+ // VirtualDisplay is created for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, atLeastOnce()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
/**
* Tests that the virtual display is created with
* {@link VirtualDisplayConfig.Builder#setSurface(Surface)}
diff --git a/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java b/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
index 56d01b0..5e7dc33 100644
--- a/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/BiasSchedulingTest.java
@@ -21,6 +21,7 @@
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
+import android.os.DeviceIdleManager;
import android.test.AndroidTestCase;
import com.android.server.job.MockBiasJobService.TestEnvironment;
@@ -48,6 +49,7 @@
sJobServiceComponent = new ComponentName(getContext(), MockBiasJobService.class);
mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
mJobScheduler.cancelAll();
+ getContext().getSystemService(DeviceIdleManager.class).endIdle("BiasSchedulingTest");
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
index 6f89ff0..2a9c18c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
@@ -157,6 +157,20 @@
checkAllColumns_latest();
}
+ @Test
+ public void onUpgradeToV7_ignoresDuplicateColumnError() throws Exception {
+ mDatabaseHelper.onCreate(mDatabase);
+ mDatabaseHelper.onUpgrade(mDatabase, 6, 7);
+ checkAllColumns_latest();
+ }
+
+ @Test
+ public void onUpgradeToV7_recreatesDatabaseAfterFailure() throws Exception {
+ mDatabaseHelper.onCreate(mDatabase);
+ mDatabaseHelper.onUpgrade(mDatabase, 1, 7);
+ checkAllColumns_latest();
+ }
+
private boolean isRootOfTrustTableAvailable() {
ContentValues values = new ContentValues();
values.put(RootOfTrustEntry.COLUMN_NAME_USER_ID, TEST_USER_ID);
diff --git a/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
index ccf530f..ba91647 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
@@ -719,8 +719,60 @@
public void testHandleUsageEvent_packageAddedThroughAdb() throws
NoSuchFieldException, PackageManager.NameNotFoundException {
assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+ // This test is a duplicate of testHandleUsageEvent_packageAddedThroughAdb except the
+ // initiatingPackageName used to be null but is now "com.android.shell". This test ensures
+ // that the behavior is still the same for when the initiatingPackageName is null.
InstallSourceInfo installSourceInfo = new InstallSourceInfo(
- /* initiatingPackageName = */ null, //currently ADB installer sets field to null
+ /* initiatingPackageName = */ null,
+ /* initiatingPackageSigningInfo = */ null,
+ /* originatingPackageName = */ null,
+ /* installingPackageName = */ INSTALLER_NAME_1);
+ // b/265203007
+ when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(installSourceInfo);
+ ApplicationInfo appInfo = mock(ApplicationInfo.class);
+
+ when(mPackageManager.getApplicationInfoAsUser(
+ eq(PACKAGE_NAME_1),
+ any(),
+ anyInt())
+ ).thenReturn(appInfo);
+
+ long createTimestamp = PACKAGE_ADD_TIMESTAMP_1
+ - (System.currentTimeMillis() - SystemClock.uptimeMillis());
+ FieldSetter.setField(appInfo,
+ ApplicationInfo.class.getDeclaredField("createTimestamp"),
+ createTimestamp);
+
+ int uid = USER_ID_1 * UserHandle.PER_USER_RANGE;
+ assertEquals(USER_ID_1, UserHandle.getUserId(uid));
+
+ // The following usage events generation is the same as
+ // testHandleUsageEvent_packageAddedOutsideTimeFrame2 test. The only difference is that
+ // for ADB installs the initiatingPackageName used to be null, despite being detected
+ // as a background install. Since we do not want to treat side-loaded apps as background
+ // install getBackgroundInstalledPackages() is expected to return null
+ doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
+ anyString(), anyString(), anyInt());
+ generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
+ USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_2);
+ generateUsageEvent(Event.ACTIVITY_STOPPED,
+ USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_3);
+
+ mPackageListObserver.onPackageAdded(PACKAGE_NAME_1, uid);
+ mTestLooper.dispatchAll();
+
+ var packages = mBackgroundInstallControlService.getBackgroundInstalledPackages();
+ assertNull(packages);
+ }
+ @Test
+ public void testHandleUsageEvent_packageAddedThroughAdb2() throws
+ NoSuchFieldException, PackageManager.NameNotFoundException {
+ assertNull(mBackgroundInstallControlService.getBackgroundInstalledPackages());
+ // This test is a duplicate of testHandleUsageEvent_packageAddedThroughAdb except the
+ // initiatingPackageName used to be null but is now "com.android.shell". This test ensures
+ // that the behavior is still the same after this change.
+ InstallSourceInfo installSourceInfo = new InstallSourceInfo(
+ /* initiatingPackageName = */ "com.android.shell",
/* initiatingPackageSigningInfo = */ null,
/* originatingPackageName = */ null,
/* installingPackageName = */ INSTALLER_NAME_1);
@@ -745,9 +797,9 @@
// The following usage events generation is the same as
// testHandleUsageEvent_packageAddedOutsideTimeFrame2 test. The only difference is that
- // for ADB installs the initiatingPackageName is null, despite being detected as a
- // background install. Since we do not want to treat side-loaded apps as background install
- // getBackgroundInstalledPackages() is expected to return null
+ // for ADB installs the initiatingPackageName is com.android.shell, despite being detected
+ // as a background install. Since we do not want to treat side-loaded apps as background
+ // install getBackgroundInstalledPackages() is expected to return null
doReturn(PackageManager.PERMISSION_GRANTED).when(mPermissionManager).checkPermission(
anyString(), anyString(), anyInt());
generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 6f6e2242..bf836ae 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -884,18 +884,21 @@
@Test
public void testProto() {
mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ // existence of manual rule means it should be in output
mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelperSpy.mConfig.manualRule.pkg = "android"; // system
int n = mZenModeHelperSpy.mConfig.automaticRules.size();
List<String> ids = new ArrayList<>(n);
for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
ids.add(rule.id);
}
- ids.add("");
+ ids.add(ZenModeConfig.MANUAL_RULE_ID);
+ ids.add(""); // for ROOT_CONFIG, logged with empty string as id
List<StatsEvent> events = new LinkedList<>();
mZenModeHelperSpy.pullRules(events);
- assertEquals(n + 1, events.size());
+ assertEquals(n + 2, events.size()); // automatic rules + manual rule + root config
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == DND_MODE_RULE) {
if (builder.getInt(ZEN_MODE_FIELD_NUMBER) == ROOT_CONFIG) {
@@ -1002,7 +1005,6 @@
mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
mZenModeHelperSpy.mConfig.manualRule.enabled = true;
- mZenModeHelperSpy.mConfig.manualRule.enabler = "com.enabler";
List<StatsEvent> events = new LinkedList<>();
mZenModeHelperSpy.pullRules(events);
diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp
index 9ca2876..986fb71 100644
--- a/services/tests/voiceinteractiontests/Android.bp
+++ b/services/tests/voiceinteractiontests/Android.bp
@@ -29,6 +29,7 @@
srcs: [
"src/**/*.java",
+ ":FrameworksCoreTestDoubles-sources",
],
static_libs: [
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java
new file mode 100644
index 0000000..8694094
--- /dev/null
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2023 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.soundtrigger_middleware;
+
+import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.verify;
+
+import android.Manifest;
+import android.app.ActivityThread;
+import android.media.permission.Identity;
+import android.media.permission.IdentityContext;
+import android.media.soundtrigger.PhraseRecognitionEvent;
+import android.media.soundtrigger.PhraseRecognitionExtra;
+import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionStatus;
+import android.media.soundtrigger_middleware.ISoundTriggerCallback;
+import android.media.soundtrigger_middleware.ISoundTriggerModule;
+import android.os.BatteryStatsInternal;
+import android.os.Process;
+import android.os.RemoteException;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.util.FakeLatencyTracker;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@RunWith(JUnit4.class)
+public class SoundTriggerMiddlewareLoggingTest {
+ private FakeLatencyTracker mLatencyTracker;
+ @Mock
+ private BatteryStatsInternal mBatteryStatsInternal;
+ @Mock
+ private ISoundTriggerMiddlewareInternal mDelegateMiddleware;
+ @Mock
+ private ISoundTriggerCallback mISoundTriggerCallback;
+ @Mock
+ private ISoundTriggerModule mSoundTriggerModule;
+ private SoundTriggerMiddlewareLogging mSoundTriggerMiddlewareLogging;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .adoptShellPermissionIdentity(Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.READ_DEVICE_CONFIG);
+
+ Identity identity = new Identity();
+ identity.uid = Process.myUid();
+ identity.pid = Process.myPid();
+ identity.packageName = ActivityThread.currentOpPackageName();
+ IdentityContext.create(identity);
+
+ mLatencyTracker = FakeLatencyTracker.create();
+ mLatencyTracker.forceEnabled(ACTION_SHOW_VOICE_INTERACTION, -1);
+ mSoundTriggerMiddlewareLogging = new SoundTriggerMiddlewareLogging(mLatencyTracker,
+ () -> mBatteryStatsInternal,
+ mDelegateMiddleware);
+ }
+
+ @After
+ public void tearDown() {
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .dropShellPermissionIdentity();
+ }
+
+ @Test
+ public void testSetUpAndTearDown() {
+ }
+
+ @Test
+ public void testOnPhraseRecognitionStartsLatencyTrackerWithSuccessfulPhraseIdTrigger()
+ throws RemoteException {
+ ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+ ISoundTriggerCallback.class);
+ mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+ verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+ triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+ RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+
+ assertThat(mLatencyTracker.getActiveActionStartTime(
+ ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
+ }
+
+ @Test
+ public void testOnPhraseRecognitionRestartsActiveSession() throws RemoteException {
+ ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+ ISoundTriggerCallback.class);
+ mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+ verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+ triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+ RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+ long firstTriggerSessionStartTime = mLatencyTracker.getActiveActionStartTime(
+ ACTION_SHOW_VOICE_INTERACTION);
+ triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+ RecognitionStatus.SUCCESS, Optional.of(100) /* keyphraseId */);
+ assertThat(mLatencyTracker.getActiveActionStartTime(
+ ACTION_SHOW_VOICE_INTERACTION)).isGreaterThan(-1);
+ assertThat(mLatencyTracker.getActiveActionStartTime(
+ ACTION_SHOW_VOICE_INTERACTION)).isNotEqualTo(firstTriggerSessionStartTime);
+ }
+
+ @Test
+ public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNonSuccessEvent()
+ throws RemoteException {
+ ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+ ISoundTriggerCallback.class);
+ mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+ verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+ triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+ RecognitionStatus.ABORTED, Optional.of(100) /* keyphraseId */);
+
+ assertThat(
+ mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
+ -1);
+ }
+
+ @Test
+ public void testOnPhraseRecognitionNeverStartsLatencyTrackerWithNoKeyphraseId()
+ throws RemoteException {
+ ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
+ ISoundTriggerCallback.class);
+ mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
+ verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
+
+ triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
+ RecognitionStatus.SUCCESS, Optional.empty() /* keyphraseId */);
+
+ assertThat(
+ mLatencyTracker.getActiveActionStartTime(ACTION_SHOW_VOICE_INTERACTION)).isEqualTo(
+ -1);
+ }
+
+ private void triggerPhraseRecognitionEvent(ISoundTriggerCallback callback,
+ @RecognitionStatus int triggerEventStatus, Optional<Integer> optionalKeyphraseId)
+ throws RemoteException {
+ // trigger a phrase recognition to start a latency tracker session
+ PhraseRecognitionEvent successEventWithKeyphraseId = new PhraseRecognitionEvent();
+ successEventWithKeyphraseId.common = new RecognitionEvent();
+ successEventWithKeyphraseId.common.status = triggerEventStatus;
+ if (optionalKeyphraseId.isPresent()) {
+ PhraseRecognitionExtra recognitionExtra = new PhraseRecognitionExtra();
+ recognitionExtra.id = optionalKeyphraseId.get();
+ successEventWithKeyphraseId.phraseExtras =
+ new PhraseRecognitionExtra[]{recognitionExtra};
+ }
+ callback.onPhraseRecognition(0 /* modelHandle */, successEventWithKeyphraseId,
+ 0 /* captureSession */);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 6dd4f2a..226ecf4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -790,7 +792,7 @@
// ... until half-fold
mTarget.foldStateChanged(DeviceStateController.DeviceState.HALF_FOLDED);
assertTrue(waitForUiHandler());
- verify(sMockWm).updateRotation(false, false);
+ verify(sMockWm).updateRotation(anyBoolean(), anyBoolean());
assertTrue(waitForUiHandler());
assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation(
SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0));
@@ -798,7 +800,7 @@
// ... then transition back to flat
mTarget.foldStateChanged(DeviceStateController.DeviceState.OPEN);
assertTrue(waitForUiHandler());
- verify(sMockWm, atLeast(1)).updateRotation(false, false);
+ verify(sMockWm, atLeast(1)).updateRotation(anyBoolean(), anyBoolean());
assertTrue(waitForUiHandler());
assertEquals(Surface.ROTATION_270, mTarget.rotationForOrientation(
SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0));
@@ -866,6 +868,23 @@
}
@Test
+ public void testIgnoresDeskDockRotation_whenNoSensorAndLockedRespected() throws Exception {
+ mBuilder.setDeskDockRotation(Surface.ROTATION_270).build();
+ when(mMockDisplayPolicy.isDeskDockRespectsNoSensorAndLockedWithoutAccelerometer())
+ .thenReturn(true);
+ configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
+
+ when(mMockDisplayPolicy.getDockMode()).thenReturn(Intent.EXTRA_DOCK_STATE_DESK);
+
+ freezeRotation(Surface.ROTATION_90);
+
+ assertEquals(Surface.ROTATION_90, mTarget.rotationForOrientation(
+ SCREEN_ORIENTATION_LOCKED, Surface.ROTATION_90));
+ assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation(
+ SCREEN_ORIENTATION_NOSENSOR, Surface.ROTATION_90));
+ }
+
+ @Test
public void testReturnsUserRotation_FixedToUserRotation_IgnoreIncompatibleAppRequest()
throws Exception {
mBuilder.build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 9b4cb13..3ae1317 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -21,6 +21,7 @@
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
@@ -46,6 +47,8 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.LetterboxUiController.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
+import static com.android.server.wm.LetterboxUiController.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -186,6 +189,69 @@
}
@Test
+ public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
+ doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ // Request 3 times to simulate orientation request loop
+ for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ 0);
+ }
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
+ doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ // Request 3 times to simulate orientation request loop
+ for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ i);
+ }
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
+ doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ // No orientation request loop
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ 0);
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse()
+ throws InterruptedException {
+ doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ for (int i = MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i > 0; i--) {
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ 0);
+ Thread.sleep(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
+ }
+ }
+
+ @Test
+ @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+ public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
+ doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
+ for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
+ /* expectedCount */ i);
+ }
+ assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ true,
+ /* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
+ }
+
+ private void assertShouldIgnoreOrientationRequestLoop(boolean shouldIgnore, int expectedCount) {
+ if (shouldIgnore) {
+ assertTrue(mController.shouldIgnoreOrientationRequestLoop());
+ } else {
+ assertFalse(mController.shouldIgnoreOrientationRequestLoop());
+ }
+ assertEquals(expectedCount, mController.getSetOrientationRequestCounter());
+ }
+
+ @Test
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index a17e124..dfc453f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -775,7 +775,7 @@
// Assume the task is at the topmost position
assertFalse(rootTask.isTopRootTaskInDisplayArea());
- doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
+ doReturn(taskDisplayArea.getHomeActivity()).when(taskDisplayArea).topRunningActivity();
// Use the task as target to resume.
mRootWindowContainer.resumeFocusedTasksTopActivities();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index adc3db7..d1f01d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
@@ -51,6 +52,7 @@
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED;
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
+import static com.android.server.wm.ActivityRecord.State.DESTROYED;
import static com.android.server.wm.ActivityRecord.State.PAUSED;
import static com.android.server.wm.ActivityRecord.State.RESTARTING_PROCESS;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
@@ -63,6 +65,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -173,6 +177,26 @@
}
@Test
+ public void testCleanLetterboxConfigListenerWhenTranslucentIsDestroyed() {
+ mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
+ setUpDisplaySizeWithApp(2000, 1000);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ // Translucent Activity
+ final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+ .setLaunchedFromUid(mActivity.getUid())
+ .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+ .build();
+ doReturn(false).when(translucentActivity).fillsParent();
+ mTask.addChild(translucentActivity);
+
+ translucentActivity.setState(DESTROYED, "testing");
+ translucentActivity.removeImmediately();
+
+ assertFalse(translucentActivity.mLetterboxUiController.hasInheritedLetterboxBehavior());
+ }
+
+ @Test
public void testHorizontalReachabilityEnabledForTranslucentActivities() {
setUpDisplaySizeWithApp(2500, 1000);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -352,6 +376,33 @@
}
@Test
+ public void testApplyStrategyToTranslucentActivitiesRetainsWindowConfigurationProperties() {
+ mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
+ setUpDisplaySizeWithApp(2000, 1000);
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ // Translucent Activity
+ final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+ .setLaunchedFromUid(mActivity.getUid())
+ .build();
+ doReturn(false).when(translucentActivity).fillsParent();
+ WindowConfiguration translucentWinConf = translucentActivity.getWindowConfiguration();
+ translucentActivity.setActivityType(ACTIVITY_TYPE_STANDARD);
+ translucentActivity.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ translucentActivity.setDisplayWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ translucentActivity.setAlwaysOnTop(true);
+
+ mTask.addChild(translucentActivity);
+
+ // We check the WIndowConfiguration properties
+ translucentWinConf = translucentActivity.getWindowConfiguration();
+ assertEquals(ACTIVITY_TYPE_STANDARD, translucentActivity.getActivityType());
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, translucentWinConf.getWindowingMode());
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, translucentWinConf.getDisplayWindowingMode());
+ assertTrue(translucentWinConf.isAlwaysOnTop());
+ }
+
+ @Test
public void testApplyStrategyToMultipleTranslucentActivities() {
mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
setUpDisplaySizeWithApp(2000, 1000);
@@ -418,7 +469,7 @@
.setLaunchedFromUid(mActivity.getUid())
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
.build();
- doReturn(true).when(translucentActivity).fillsParent();
+ doReturn(false).when(translucentActivity).fillsParent();
mTask.addChild(translucentActivity);
// It should not be in SCM
assertFalse(translucentActivity.inSizeCompatMode());
@@ -479,6 +530,33 @@
}
@Test
+ public void testTranslucentActivity_clearSizeCompatMode_inheritedCompatDisplayInsetsCleared() {
+ mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
+ setUpDisplaySizeWithApp(2800, 1400);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ // Rotate to put activity in size compat mode.
+ rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+ assertTrue(mActivity.inSizeCompatMode());
+
+ // We launch a transparent activity
+ final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+ .setLaunchedFromUid(mActivity.getUid())
+ .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+ .build();
+ doReturn(false).when(translucentActivity).fillsParent();
+ mTask.addChild(translucentActivity);
+
+ // The transparent activity inherits the compat display insets of the opaque activity
+ // beneath it
+ assertNotNull(translucentActivity.getCompatDisplayInsets());
+
+ // Clearing SCM should also clear the inherited compat display insets
+ translucentActivity.clearSizeCompatMode();
+ assertNull(translucentActivity.getCompatDisplayInsets());
+ }
+
+ @Test
public void testRestartProcessIfVisible() {
setUpDisplaySizeWithApp(1000, 2500);
doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
@@ -3085,12 +3163,44 @@
assertTrue(mActivity.inSizeCompatMode());
// Vertical reachability is disabled because the app does not match parent width
- assertNotEquals(mActivity.getBounds().width(), mActivity.mDisplayContent.getBounds()
- .width());
+ assertNotEquals(mActivity.getScreenResolvedBounds().width(),
+ mActivity.mDisplayContent.getBounds().width());
assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
}
@Test
+ public void testIsVerticalReachabilityEnabled_emptyBounds_true() {
+ setUpDisplaySizeWithApp(/* dw */ 1000, /* dh */ 2800);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+ // Set up activity with empty bounds to mock loading of app
+ mActivity.getWindowConfiguration().setBounds(null);
+ assertEquals(new Rect(0, 0, 0, 0), mActivity.getBounds());
+
+ // Vertical reachability is still enabled as resolved bounds is not empty
+ assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+ }
+
+ @Test
+ public void testIsHorizontalReachabilityEnabled_emptyBounds_true() {
+ setUpDisplaySizeWithApp(/* dw */ 2800, /* dh */ 1000);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+
+ prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+ // Set up activity with empty bounds to mock loading of app
+ mActivity.getWindowConfiguration().setBounds(null);
+ assertEquals(new Rect(0, 0, 0, 0), mActivity.getBounds());
+
+ // Horizontal reachability is still enabled as resolved bounds is not empty
+ assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+ }
+
+ @Test
public void testIsHorizontalReachabilityEnabled_doesNotMatchParentHeight_false() {
setUpDisplaySizeWithApp(2800, 1000);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -3106,8 +3216,8 @@
assertTrue(mActivity.inSizeCompatMode());
// Horizontal reachability is disabled because the app does not match parent height
- assertNotEquals(mActivity.getBounds().height(), mActivity.mDisplayContent.getBounds()
- .height());
+ assertNotEquals(mActivity.getScreenResolvedBounds().height(),
+ mActivity.mDisplayContent.getBounds().height());
assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
}
@@ -3127,8 +3237,8 @@
assertTrue(mActivity.inSizeCompatMode());
// Horizontal reachability is enabled because the app matches parent height
- assertEquals(mActivity.getBounds().height(), mActivity.mDisplayContent.getBounds()
- .height());
+ assertEquals(mActivity.getScreenResolvedBounds().height(),
+ mActivity.mDisplayContent.getBounds().height());
assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
}
@@ -3148,7 +3258,8 @@
assertTrue(mActivity.inSizeCompatMode());
// Vertical reachability is enabled because the app matches parent width
- assertEquals(mActivity.getBounds().width(), mActivity.mDisplayContent.getBounds().width());
+ assertEquals(mActivity.getScreenResolvedBounds().width(),
+ mActivity.mDisplayContent.getBounds().width());
assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
}
@@ -3670,7 +3781,6 @@
@Test
public void testUpdateResolvedBoundsVerticalPosition_tabletop() {
-
// Set up a display in portrait with a fixed-orientation LANDSCAPE app
setUpDisplaySizeWithApp(1400, 2800);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -3692,16 +3802,15 @@
setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
assertEquals(letterboxNoFold, mActivity.getBounds());
-
}
@Test
- public void testUpdateResolvedBoundsHorizontalPosition_book() {
-
+ public void testUpdateResolvedBoundsHorizontalPosition_bookModeEnabled() {
// Set up a display in landscape with a fixed-orientation PORTRAIT app
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
+ mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true);
+ mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
1.0f /*letterboxVerticalPositionMultiplier*/);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
@@ -3719,7 +3828,28 @@
setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
assertEquals(letterboxNoFold, mActivity.getBounds());
+ }
+ @Test
+ public void testUpdateResolvedBoundsHorizontalPosition_bookModeDisabled_centered() {
+ // Set up a display in landscape with a fixed-orientation PORTRAIT app
+ setUpDisplaySizeWithApp(2800, 1400);
+ mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
+ prepareUnresizable(mActivity, 1.75f, SCREEN_ORIENTATION_PORTRAIT);
+
+ Rect letterboxNoFold = new Rect(1000, 0, 1800, 1400);
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ // Make the activity full-screen
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+ // Stay centered and bounds don't change
+ setFoldablePosture(true /* isHalfFolded */, false /* isTabletop */);
+ assertEquals(letterboxNoFold, mActivity.getBounds());
+
+ setFoldablePosture(false /* isHalfFolded */, false /* isTabletop */);
+ assertEquals(letterboxNoFold, mActivity.getBounds());
}
private void setFoldablePosture(ActivityRecord activity, boolean isHalfFolded,
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 1a1af3b..2975e1e 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -1362,12 +1362,10 @@
}
}
- // Need to create new version to prevent double counting existing stats due
- // to new broadcast
private void logToStatsdComplianceWarnings(PortInfo portInfo) {
- if (portInfo.mUsbPortStatus == null) {
- FrameworkStatsLog.write(FrameworkStatsLog.USB_COMPLIANCE_WARNINGS_REPORTED,
- portInfo.mUsbPort.getId(), new int[0]);
+ // Don't report if there isn't anything to report
+ if (portInfo.mUsbPortStatus == null
+ || portInfo.mUsbPortStatus.getComplianceWarnings().length == 0) {
return;
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 70af337..04c1c04 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -44,6 +44,7 @@
import android.content.pm.ResolveInfo;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.ModelParams;
+import android.hardware.soundtrigger.ConversionUtil;
import android.hardware.soundtrigger.SoundTrigger;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
@@ -63,6 +64,7 @@
import android.media.soundtrigger.ISoundTriggerDetectionService;
import android.media.soundtrigger.ISoundTriggerDetectionServiceClient;
import android.media.soundtrigger.SoundTriggerDetectionService;
+import android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -72,6 +74,8 @@
import android.os.ParcelUuid;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -88,11 +92,13 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.UUID;
+import java.util.stream.Collectors;
import java.util.concurrent.TimeUnit;
/**
@@ -215,14 +221,29 @@
}
}
+ // Must be called with cleared binder context.
+ private static List<ModuleProperties> listUnderlyingModuleProperties(
+ Identity originatorIdentity) {
+ Identity middlemanIdentity = new Identity();
+ middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
+ var service = ISoundTriggerMiddlewareService.Stub.asInterface(
+ ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
+ try {
+ return Arrays.stream(service.listModulesAsMiddleman(middlemanIdentity,
+ originatorIdentity))
+ .map(desc -> ConversionUtil.aidl2apiModuleDescriptor(desc))
+ .collect(Collectors.toList());
+ } catch (RemoteException e) {
+ throw new ServiceSpecificException(SoundTrigger.STATUS_DEAD_OBJECT);
+ }
+ }
+
private SoundTriggerHelper newSoundTriggerHelper(ModuleProperties moduleProperties) {
Identity middlemanIdentity = new Identity();
middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
Identity originatorIdentity = IdentityContext.getNonNull();
- ArrayList<ModuleProperties> moduleList = new ArrayList<>();
- SoundTrigger.listModulesAsMiddleman(moduleList, middlemanIdentity,
- originatorIdentity);
+ List<ModuleProperties> moduleList = listUnderlyingModuleProperties(originatorIdentity);
// Don't fail existing CTS tests which run without a ST module
final int moduleId = (moduleProperties != null) ?
@@ -241,12 +262,8 @@
moduleId, statusListener, null /* handler */,
middlemanIdentity, originatorIdentity),
moduleId,
- () -> {
- ArrayList<ModuleProperties> modulePropList = new ArrayList<>();
- SoundTrigger.listModulesAsMiddleman(modulePropList, middlemanIdentity,
- originatorIdentity);
- return modulePropList;
- });
+ () -> listUnderlyingModuleProperties(originatorIdentity)
+ );
}
class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
@@ -276,12 +293,7 @@
public List<ModuleProperties> listModuleProperties(@NonNull Identity originatorIdentity) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
- Identity middlemanIdentity = new Identity();
- middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
- ArrayList<ModuleProperties> moduleList = new ArrayList<>();
- SoundTrigger.listModulesAsMiddleman(moduleList, middlemanIdentity,
- originatorIdentity);
- return moduleList;
+ return listUnderlyingModuleProperties(originatorIdentity);
}
}
}
@@ -1647,17 +1659,10 @@
@Override
public List<ModuleProperties> listModuleProperties(Identity originatorIdentity) {
- ArrayList<ModuleProperties> moduleList = new ArrayList<>();
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
- Identity middlemanIdentity = new Identity();
- middlemanIdentity.uid = Binder.getCallingUid();
- middlemanIdentity.pid = Binder.getCallingPid();
- middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
- SoundTrigger.listModulesAsMiddleman(moduleList, middlemanIdentity,
- originatorIdentity);
+ return listUnderlyingModuleProperties(originatorIdentity);
}
- return moduleList;
}
@Override
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
index 7d5750e..2f8d17d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java
@@ -26,6 +26,7 @@
import android.media.soundtrigger.PhraseSoundModel;
import android.media.soundtrigger.RecognitionConfig;
import android.media.soundtrigger.RecognitionEvent;
+import android.media.soundtrigger.RecognitionStatus;
import android.media.soundtrigger.SoundModel;
import android.media.soundtrigger_middleware.ISoundTriggerCallback;
import android.media.soundtrigger_middleware.ISoundTriggerModule;
@@ -36,6 +37,8 @@
import android.os.SystemClock;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.LatencyTracker;
import com.android.server.LocalServices;
@@ -44,6 +47,7 @@
import java.util.Date;
import java.util.LinkedList;
import java.util.Objects;
+import java.util.function.Supplier;
/**
* An ISoundTriggerMiddlewareService decorator, which adds logging of all API calls (and
@@ -71,12 +75,23 @@
public class SoundTriggerMiddlewareLogging implements ISoundTriggerMiddlewareInternal, Dumpable {
private static final String TAG = "SoundTriggerMiddlewareLogging";
private final @NonNull ISoundTriggerMiddlewareInternal mDelegate;
- private final @NonNull Context mContext;
+ private final @NonNull LatencyTracker mLatencyTracker;
+ private final @NonNull Supplier<BatteryStatsInternal> mBatteryStatsInternalSupplier;
public SoundTriggerMiddlewareLogging(@NonNull Context context,
@NonNull ISoundTriggerMiddlewareInternal delegate) {
+ this(LatencyTracker.getInstance(context),
+ () -> BatteryStatsHolder.INSTANCE,
+ delegate);
+ }
+
+ @VisibleForTesting
+ public SoundTriggerMiddlewareLogging(@NonNull LatencyTracker latencyTracker,
+ @NonNull Supplier<BatteryStatsInternal> batteryStatsInternalSupplier,
+ @NonNull ISoundTriggerMiddlewareInternal delegate) {
mDelegate = delegate;
- mContext = context;
+ mLatencyTracker = latencyTracker;
+ mBatteryStatsInternalSupplier = batteryStatsInternalSupplier;
}
@Override
@@ -294,7 +309,7 @@
public void onRecognition(int modelHandle, RecognitionEvent event, int captureSession)
throws RemoteException {
try {
- BatteryStatsHolder.INSTANCE.noteWakingSoundTrigger(
+ mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
mCallbackDelegate.onRecognition(modelHandle, event, captureSession);
logVoidReturn("onRecognition", modelHandle, event);
@@ -309,7 +324,7 @@
int captureSession)
throws RemoteException {
try {
- BatteryStatsHolder.INSTANCE.noteWakingSoundTrigger(
+ mBatteryStatsInternalSupplier.get().noteWakingSoundTrigger(
SystemClock.elapsedRealtime(), mOriginatorIdentity.uid);
startKeyphraseEventLatencyTracking(event);
mCallbackDelegate.onPhraseRecognition(modelHandle, event, captureSession);
@@ -361,26 +376,6 @@
logVoidReturnWithObject(this, mOriginatorIdentity, methodName, args);
}
- /**
- * Starts the latency tracking log for keyphrase hotword invocation.
- * The measurement covers from when the SoundTrigger HAL emits an event to when the
- * {@link android.service.voice.VoiceInteractionSession} system UI view is shown.
- */
- private void startKeyphraseEventLatencyTracking(PhraseRecognitionEvent event) {
- String latencyTrackerTag = null;
- if (event.phraseExtras.length > 0) {
- latencyTrackerTag = "KeyphraseId=" + event.phraseExtras[0].id;
- }
- LatencyTracker latencyTracker = LatencyTracker.getInstance(mContext);
- // To avoid adding cancel to all of the different failure modes between here and
- // showing the system UI, we defensively cancel once.
- // Either we hit the LatencyTracker timeout of 15 seconds or we defensively cancel
- // here if any error occurs.
- latencyTracker.onActionCancel(LatencyTracker.ACTION_SHOW_VOICE_INTERACTION);
- latencyTracker.onActionStart(LatencyTracker.ACTION_SHOW_VOICE_INTERACTION,
- latencyTrackerTag);
- }
-
@Override
public IBinder asBinder() {
return mCallbackDelegate.asBinder();
@@ -399,6 +394,29 @@
LocalServices.getService(BatteryStatsInternal.class);
}
+ /**
+ * Starts the latency tracking log for keyphrase hotword invocation.
+ * The measurement covers from when the SoundTrigger HAL emits an event to when the
+ * {@link android.service.voice.VoiceInteractionSession} system UI view is shown.
+ *
+ * <p>The session is only started if the {@link PhraseRecognitionEvent} has a status of
+ * {@link RecognitionStatus#SUCCESS}
+ */
+ private void startKeyphraseEventLatencyTracking(PhraseRecognitionEvent event) {
+ if (event.common.status != RecognitionStatus.SUCCESS
+ || ArrayUtils.isEmpty(event.phraseExtras)) {
+ return;
+ }
+
+ String latencyTrackerTag = "KeyphraseId=" + event.phraseExtras[0].id;
+ // To avoid adding cancel to all the different failure modes between here and
+ // showing the system UI, we defensively cancel once.
+ // Either we hit the LatencyTracker timeout of 15 seconds or we defensively cancel
+ // here if any error occurs.
+ mLatencyTracker.onActionCancel(LatencyTracker.ACTION_SHOW_VOICE_INTERACTION);
+ mLatencyTracker.onActionStart(LatencyTracker.ACTION_SHOW_VOICE_INTERACTION,
+ latencyTrackerTag);
+ }
////////////////////////////////////////////////////////////////////////////////////////////////
// Actual logging logic below.
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
index c35d90f..f7b66a2 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -34,10 +34,13 @@
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
+import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+import android.content.Context;
import android.service.voice.HotwordDetector;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.LatencyTracker;
/**
* A utility class for logging hotword statistics event.
@@ -116,6 +119,46 @@
metricsDetectorType, event, uid, streamSizeBytes, bundleSizeBytes, streamCount);
}
+ /**
+ * Starts a {@link LatencyTracker} log for the time it takes to show the
+ * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
+ *
+ * @see LatencyTracker
+ *
+ * @param tag Extra tag to separate different sessions from each other.
+ */
+ public static void startHotwordTriggerToUiLatencySession(Context context, String tag) {
+ LatencyTracker.getInstance(context).onActionStart(ACTION_SHOW_VOICE_INTERACTION, tag);
+ }
+
+ /**
+ * Completes a {@link LatencyTracker} log for the time it takes to show the
+ * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
+ *
+ * <p>Completing this session will result in logging metric data.</p>
+ *
+ * @see LatencyTracker
+ */
+ public static void stopHotwordTriggerToUiLatencySession(Context context) {
+ LatencyTracker.getInstance(context).onActionEnd(ACTION_SHOW_VOICE_INTERACTION);
+ }
+
+ /**
+ * Cancels a {@link LatencyTracker} log for the time it takes to show the
+ * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
+ *
+ * <p>Cancels typically occur when the VoiceInteraction session UI is shown for reasons outside
+ * of a {@link android.hardware.soundtrigger.SoundTrigger.RecognitionEvent} such as an
+ * invocation from an external source or service.</p>
+ *
+ * <p>Canceling this session will not result in logging metric data.
+ *
+ * @see LatencyTracker
+ */
+ public static void cancelHotwordTriggerToUiLatencySession(Context context) {
+ LatencyTracker.getInstance(context).onActionCancel(ACTION_SHOW_VOICE_INTERACTION);
+ }
+
private static int getCreateMetricsDetectorType(int detectorType) {
switch (detectorType) {
case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 1a76295..e1da2ca 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -97,7 +97,6 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
-import com.android.internal.util.LatencyTracker;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -443,6 +442,10 @@
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
+ // HotwordDetector trigger uses VoiceInteractionService#showSession
+ // We need to cancel here because UI is not being shown due to a SoundTrigger
+ // HAL event.
+ HotwordMetricsLogger.cancelHotwordTriggerToUiLatencySession(mContext);
mImpl.showSessionLocked(options,
VoiceInteractionSession.SHOW_SOURCE_ACTIVITY, attributionTag,
new IVoiceInteractionSessionShowCallback.Stub() {
@@ -994,6 +997,13 @@
Slog.w(TAG, "showSessionFromSession without running voice interaction service");
return false;
}
+ // If the token is null, then the request to show the session is not coming from
+ // the active VoiceInteractionService session.
+ // We need to cancel here because UI is not being shown due to a SoundTrigger
+ // HAL event.
+ if (token == null) {
+ HotwordMetricsLogger.cancelHotwordTriggerToUiLatencySession(mContext);
+ }
final long caller = Binder.clearCallingIdentity();
try {
return mImpl.showSessionLocked(sessionArgs, flags, attributionTag, null, null);
@@ -1862,6 +1872,11 @@
final long caller = Binder.clearCallingIdentity();
try {
+ // HotwordDetector trigger uses VoiceInteractionService#showSession
+ // We need to cancel here because UI is not being shown due to a SoundTrigger
+ // HAL event.
+ HotwordMetricsLogger.cancelHotwordTriggerToUiLatencySession(mContext);
+
return mImpl.showSessionLocked(args,
sourceFlags
| VoiceInteractionSession.SHOW_WITH_ASSIST
@@ -2521,8 +2536,11 @@
public void onVoiceSessionWindowVisibilityChanged(boolean visible)
throws RemoteException {
if (visible) {
- LatencyTracker.getInstance(mContext)
- .onActionEnd(LatencyTracker.ACTION_SHOW_VOICE_INTERACTION);
+ // The AlwaysOnHotwordDetector trigger latency is always completed here even
+ // if the reason the window was shown was not due to a SoundTrigger HAL
+ // event. It is expected that the latency will be canceled if shown for
+ // other invocation reasons, and this call becomes a noop.
+ HotwordMetricsLogger.stopHotwordTriggerToUiLatencySession(mContext);
}
}
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 0325ba6..f9b76f4 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
@@ -255,15 +256,26 @@
* Show switch to managed profile dialog if subscription is associated with managed profile.
*
* @param context Context object
- * @param subId subscription id
+ * @param subId subscription id
+ * @param callingUid uid for the calling app
+ * @param callingPackage package name of the calling app
*/
- public static void showErrorIfSubscriptionAssociatedWithManagedProfile(Context context,
- int subId) {
+ public static void showSwitchToManagedProfileDialogIfAppropriate(Context context,
+ int subId, int callingUid, String callingPackage) {
if (!isSwitchToManagedProfileDialogFlagEnabled()) {
return;
}
final long token = Binder.clearCallingIdentity();
try {
+ UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid);
+ // We only want to show this dialog, while user actually trying to send the message from
+ // a messaging app, in other cases this dialog don't make sense.
+ if (!TelephonyUtils.isUidForeground(context, callingUid)
+ || !TelephonyUtils.isPackageSMSRoleHolderForUser(context, callingPackage,
+ callingUserHandle)) {
+ return;
+ }
+
SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
UserHandle associatedUserHandle = subscriptionManager.getSubscriptionUserHandle(subId);
@@ -295,22 +307,25 @@
"enable_switch_to_managed_profile_dialog", false);
}
- /**
- * Check if the process with given uid is foreground.
- *
- * @param context context
- * @param uid the caller uid
- * @return true if the process with uid is foreground, false otherwise.
- */
- public static boolean isUidForeground(Context context, int uid) {
- final long token = Binder.clearCallingIdentity();
- try {
- ActivityManager am = context.getSystemService(ActivityManager.class);
- boolean result = am != null && am.getUidImportance(uid)
- == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
- return result;
- } finally {
- Binder.restoreCallingIdentity(token);
+ private static boolean isUidForeground(Context context, int uid) {
+ ActivityManager am = context.getSystemService(ActivityManager.class);
+ boolean result = am != null && am.getUidImportance(uid)
+ == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+ return result;
+ }
+
+ private static boolean isPackageSMSRoleHolderForUser(Context context, String callingPackage,
+ UserHandle user) {
+ RoleManager roleManager = context.getSystemService(RoleManager.class);
+ final List<String> smsRoleHolder = roleManager.getRoleHoldersAsUser(
+ RoleManager.ROLE_SMS, user);
+
+ // ROLE_SMS is an exclusive role per user, so there would just be one entry in the
+ // retuned list if not empty
+ if (!smsRoleHolder.isEmpty() && callingPackage.equals(smsRoleHolder.get(0))) {
+ return true;
}
+ return false;
+
}
}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index 33c86d8..4c37f7d 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -398,7 +398,11 @@
ImsService.this.disableImsForSubscription(slotId, subId), "disableIms");
}
-
+ @Override
+ public void resetIms(int slotId, int subId) {
+ executeMethodAsync(() ->
+ ImsService.this.resetImsInternal(slotId, subId), "resetIms");
+ }
};
private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@@ -634,6 +638,14 @@
}
}
+ private void resetImsInternal(int slotId, int subId) {
+ try {
+ resetIms(slotId);
+ } catch (UnsupportedOperationException e) {
+ disableImsForSubscription(slotId, subId);
+ }
+ }
+
/**
* When called, provide the {@link ImsFeatureConfiguration} that this {@link ImsService}
* currently supports. This will trigger the framework to set up the {@link ImsFeature}s that
@@ -751,6 +763,19 @@
}
/**
+ * The framework has reset IMS for the slot specified. The ImsService must deregister
+ * and release all resources for IMS. After resetIms is called, either
+ * {@link #enableImsForSubscription(int, int)} or {@link #disableImsForSubscription(int, int)}
+ * will be called for the same slotId.
+ *
+ * @param slotId The slot ID that IMS will be reset for.
+ * @hide
+ */
+ public void resetIms(int slotId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* When called, the framework is requesting that a new {@link MmTelFeature} is created for the
* specified subscription.
*
diff --git a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
index ae6166f..fdf43a5 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl
@@ -47,4 +47,5 @@
ISipTransport getSipTransport(int slotId);
oneway void enableIms(int slotId, int subId);
oneway void disableIms(int slotId, int subId);
+ oneway void resetIms(int slotId, int subId);
}
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index 7f084f89..548dded 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -140,7 +140,8 @@
}
@Override
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+ public String[] getStreamTypes(AttributionSource attributionSource,
+ Uri url, String mimeTypeFilter) throws RemoteException {
return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
}
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index bb2996a..23f8b98 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -144,7 +144,8 @@
}
@Override
- public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+ public String[] getStreamTypes(@NonNull AttributionSource attributionSource,
+ Uri url, String mimeTypeFilter) throws RemoteException {
throw new UnsupportedOperationException("unimplemented mock method");
}
diff --git a/tests/ActivityManagerPerfTests/stub-app/AndroidManifest.xml b/tests/ActivityManagerPerfTests/stub-app/AndroidManifest.xml
index 6bdeea0..02d03bbf 100644
--- a/tests/ActivityManagerPerfTests/stub-app/AndroidManifest.xml
+++ b/tests/ActivityManagerPerfTests/stub-app/AndroidManifest.xml
@@ -19,6 +19,12 @@
package="com.android.stubs.am">
<uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
+ <queries>
+ <intent>
+ <action android:name="com.android.stubs.am.ACTION_BROADCAST_TEST"/>
+ </intent>
+ </queries>
+
<application android:label="Android TestCase">
<provider android:authorities="@string/authority"
android:name=".TestContentProvider"
diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp
index e5eb3c7..7af76e1 100644
--- a/tests/componentalias/Android.bp
+++ b/tests/componentalias/Android.bp
@@ -16,6 +16,9 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+// TODO: Delete this file. It's no longer needed, but removing it on udc-dev will cause
+// a conflict on master.
+
java_defaults {
name: "ComponentAliasTests_defaults",
static_libs: [
@@ -34,54 +37,3 @@
],
platform_apis: true, // We use hidden APIs in the test.
}
-
-// We build three APKs from the exact same source files, so these APKs contain the exact same tests.
-// And we run the tests on each APK, so that we can test various situations:
-// - When the alias is in the same package, target in the same package.
-// - When the alias is in the same package, target in another package.
-// - When the alias is in another package, which also contains the target.
-// - When the alias is in another package, and the target is in yet another package.
-// etc etc...
-
-android_test {
- name: "ComponentAliasTests",
- defaults: [
- "ComponentAliasTests_defaults",
- ],
- package_name: "android.content.componentalias.tests",
- manifest: "AndroidManifest.xml",
- additional_manifests: [
- "AndroidManifest_main.xml",
- "AndroidManifest_service_aliases.xml",
- "AndroidManifest_service_targets.xml",
- ],
- test_config_template: "AndroidTest-template.xml",
-}
-
-android_test {
- name: "ComponentAliasTests1",
- defaults: [
- "ComponentAliasTests_defaults",
- ],
- package_name: "android.content.componentalias.tests.sub1",
- manifest: "AndroidManifest.xml",
- additional_manifests: [
- "AndroidManifest_sub1.xml",
- "AndroidManifest_service_targets.xml",
- ],
- test_config_template: "AndroidTest-template.xml",
-}
-
-android_test {
- name: "ComponentAliasTests2",
- defaults: [
- "ComponentAliasTests_defaults",
- ],
- package_name: "android.content.componentalias.tests.sub2",
- manifest: "AndroidManifest.xml",
- additional_manifests: [
- "AndroidManifest_sub2.xml",
- "AndroidManifest_service_targets.xml",
- ],
- test_config_template: "AndroidTest-template.xml",
-}
diff --git a/tests/componentalias/AndroidManifest.xml b/tests/componentalias/AndroidManifest.xml
deleted file mode 100755
index 7bb83a3..0000000
--- a/tests/componentalias/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
-
- <application>
- <uses-library android:name="android.test.runner" />
- <property android:name="com.android.EXPERIMENTAL_COMPONENT_ALIAS_OPT_IN" android:value="true" />
- </application>
-</manifest>
diff --git a/tests/componentalias/AndroidManifest_main.xml b/tests/componentalias/AndroidManifest_main.xml
deleted file mode 100755
index 70e817e..0000000
--- a/tests/componentalias/AndroidManifest_main.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
-
- <application>
- </application>
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.content.componentalias.tests" >
- </instrumentation>
-</manifest>
diff --git a/tests/componentalias/AndroidManifest_service_aliases.xml b/tests/componentalias/AndroidManifest_service_aliases.xml
deleted file mode 100644
index c96f173..0000000
--- a/tests/componentalias/AndroidManifest_service_aliases.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
- <application>
- <!--
- Note the alias components are essentially just placeholders, so the APKs don't have to
- have the implementation classes.
- -->
- <service android:name=".s.Alias00" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests/android.content.componentalias.tests.s.Target00" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_00" /></intent-filter>
- </service>
- <service android:name=".s.Alias01" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.s.Target01" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_01" /></intent-filter>
- </service>
- <service android:name=".s.Alias02" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.s.Target02" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_02" /></intent-filter>
- </service>
- <service android:name=".s.Alias03" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.s.Target03" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_03" /></intent-filter>
- </service>
- <service android:name=".s.Alias04" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.s.Target04" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_ALIAS_04" /></intent-filter>
- </service>
-
- <receiver android:name=".b.Alias00" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests/android.content.componentalias.tests.b.Target00" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_00" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Alias01" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.b.Target01" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_01" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Alias02" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.b.Target02" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_02" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Alias03" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub1/android.content.componentalias.tests.b.Target03" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_03" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Alias04" android:exported="true" android:enabled="true" >
- <meta-data android:name="alias_target" android:value="android.content.componentalias.tests.sub2/android.content.componentalias.tests.b.Target04" />
- <intent-filter><action android:name="com.android.intent.action.EXPERIMENTAL_IS_ALIAS" /></intent-filter>
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_04" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- </application>
-</manifest>
diff --git a/tests/componentalias/AndroidManifest_service_targets.xml b/tests/componentalias/AndroidManifest_service_targets.xml
deleted file mode 100644
index 24c0432..0000000
--- a/tests/componentalias/AndroidManifest_service_targets.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
- <application>
- <service android:name=".s.Target00" android:exported="true" android:enabled="true" >
- </service>
- <service android:name=".s.Target01" android:exported="true" android:enabled="true" >
- </service>
- <service android:name=".s.Target02" android:exported="true" android:enabled="true" >
- </service>
- <service android:name=".s.Target03" android:exported="true" android:enabled="true" >
- </service>
- <service android:name=".s.Target04" android:exported="true" android:enabled="true" >
- </service>
-
- <!--
- Due to http://go/intents-match-intent-filters-guide, the target intent has to have
- an intent filter that matches the original intent. (modulo the package name)
- This restriction shouldn't exist in the final version.
- -->
- <receiver android:name=".b.Target00" android:exported="true" android:enabled="true" >
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_00" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Target01" android:exported="true" android:enabled="true" >
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_01" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Target02" android:exported="true" android:enabled="true" >
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_02" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Target03" android:exported="true" android:enabled="true" >
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_03" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- <receiver android:name=".b.Target04" android:exported="true" android:enabled="true" >
- <intent-filter><action android:name="android.content.componentalias.tests.IS_RECEIVER_04" /></intent-filter>
- <intent-filter><action android:name="ACTION_BROADCAST" /></intent-filter>
- </receiver>
- </application>
-</manifest>
diff --git a/tests/componentalias/AndroidManifest_sub1.xml b/tests/componentalias/AndroidManifest_sub1.xml
deleted file mode 100755
index 21616f5..0000000
--- a/tests/componentalias/AndroidManifest_sub1.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
-
- <application>
- </application>
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.content.componentalias.tests.sub1" >
- </instrumentation>
-</manifest>
diff --git a/tests/componentalias/AndroidManifest_sub2.xml b/tests/componentalias/AndroidManifest_sub2.xml
deleted file mode 100755
index c11b0cd..0000000
--- a/tests/componentalias/AndroidManifest_sub2.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.content.componentalias.tests" >
-
- <application>
- </application>
-
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.content.componentalias.tests.sub2" >
- </instrumentation>
-</manifest>
diff --git a/tests/componentalias/AndroidTest-template.xml b/tests/componentalias/AndroidTest-template.xml
deleted file mode 100644
index afdfe79..0000000
--- a/tests/componentalias/AndroidTest-template.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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.
--->
-<configuration>
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="ComponentAliasTests.apk" />
- <option name="test-file-name" value="ComponentAliasTests1.apk" />
- <option name="test-file-name" value="ComponentAliasTests2.apk" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <!-- Exempt the helper APKs from the BG restriction, so they can start BG services. -->
- <option name="run-command" value="cmd deviceidle whitelist +android.content.componentalias.tests" />
- <option name="run-command" value="cmd deviceidle whitelist +android.content.componentalias.tests.sub1" />
- <option name="run-command" value="cmd deviceidle whitelist +android.content.componentalias.tests.sub2" />
-
- <option name="teardown-command" value="cmd deviceidle whitelist -android.content.componentalias.tests" />
- <option name="teardown-command" value="cmd deviceidle whitelist -android.content.componentalias.tests.sub1" />
- <option name="teardown-command" value="cmd deviceidle whitelist -android.content.componentalias.tests.sub2" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="{PACKAGE}" />
- <option name="runtime-hint" value="2m" />
- <option name="isolated-storage" value="false" />
- </test>
-</configuration>
diff --git a/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java b/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java
deleted file mode 100644
index 99322ee..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/BaseComponentAliasTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.Build;
-import android.provider.DeviceConfig;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.DeviceConfigStateHelper;
-import com.android.compatibility.common.util.ShellUtils;
-import com.android.compatibility.common.util.TestUtils;
-
-import org.junit.AfterClass;
-import org.junit.Assume;
-import org.junit.Before;
-
-import java.util.function.Consumer;
-
-public class BaseComponentAliasTest {
- protected static final Context sContext = InstrumentationRegistry.getTargetContext();
-
- protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
- @Before
- public void enableComponentAliasWithCompatFlag() throws Exception {
- Assume.assumeTrue(Build.isDebuggable());
- ShellUtils.runShellCommand(
- "am compat enable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
- sDeviceConfig.set("enable_experimental_component_alias", "");
- sDeviceConfig.set("component_alias_overrides", "");
-
- // Make sure the feature is actually enabled, and the aliases are loaded.
- TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
- String out = ShellUtils.runShellCommand("dumpsys activity component-alias");
-
- return out.contains("Enabled: true")
- && out.contains("android.content.componentalias.tests/.b.Alias04")
- && out.contains("android.content.componentalias.tests/.s.Alias04");
- });
- ShellUtils.runShellCommand("am wait-for-broadcast-idle");
- }
-
- @AfterClass
- public static void restoreDeviceConfig() throws Exception {
- ShellUtils.runShellCommand(
- "am compat disable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
- sDeviceConfig.close();
- }
-
- protected static void log(String message) {
- Log.i(ComponentAliasTestCommon.TAG, "[" + sContext.getPackageName() + "] " + message);
- }
-
- /**
- * Defines a test target.
- */
- public static class Combo {
- public final ComponentName alias;
- public final ComponentName target;
- public final String action;
-
- public Combo(ComponentName alias, ComponentName target, String action) {
- this.alias = alias;
- this.target = target;
- this.action = action;
- }
-
- @Override
- public String toString() {
- return "Combo{"
- + "alias=" + toString(alias)
- + ", target=" + toString(target)
- + ", action='" + action + '\''
- + '}';
- }
-
- private static String toString(ComponentName cn) {
- return cn == null ? "[null]" : cn.flattenToShortString();
- }
-
- public void apply(Consumer<Combo> callback) {
- log("Testing for: " + this);
- callback.accept(this);
- }
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasBroadcastTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasBroadcastTest.java
deleted file mode 100644
index 7d5e0b9..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasBroadcastTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-import static android.content.componentalias.tests.ComponentAliasTestCommon.MAIN_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.SUB1_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.SUB2_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.TAG;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ComponentName;
-import android.content.Intent;
-
-import com.android.compatibility.common.util.BroadcastMessenger.Receiver;
-
-import org.junit.Test;
-
-import java.util.function.Consumer;
-
-public class ComponentAliasBroadcastTest extends BaseComponentAliasTest {
- private void forEachCombo(Consumer<Combo> callback) {
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".b.Alias00"),
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".b.Target00"),
- MAIN_PACKAGE + ".IS_RECEIVER_00").apply(callback);
-
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".b.Alias01"),
- new ComponentName(SUB1_PACKAGE, MAIN_PACKAGE + ".b.Target01"),
- MAIN_PACKAGE + ".IS_RECEIVER_01").apply(callback);
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".b.Alias02"),
- new ComponentName(SUB2_PACKAGE, MAIN_PACKAGE + ".b.Target02"),
- MAIN_PACKAGE + ".IS_RECEIVER_02").apply(callback);
- }
-
- @Test
- public void testBroadcast_explicitComponentName() {
- forEachCombo((c) -> {
- Intent i = new Intent().setComponent(c.alias);
- i.setAction("ACTION_BROADCAST");
- ComponentAliasMessage m;
-
- try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext, TAG)) {
- log("Sending: " + i);
- sContext.sendBroadcast(i);
-
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onReceive");
- assertThat(m.getSenderIdentity()).isEqualTo(c.target.flattenToShortString());
-
- // The broadcast intent will always have the receiving component name set.
- assertThat(m.getIntent().getComponent()).isEqualTo(c.target);
-
- receiver.ensureNoMoreMessages();
- }
- });
- }
-
- @Test
- public void testBroadcast_explicitPackageName() {
- forEachCombo((c) -> {
- // In this test, we only set the package name to the intent.
- // If the alias and target are the same package, the intent will be sent to both of them
- // *and* the one to the alias is redirected to the target, so the target will receive
- // the intent twice. This case is haled at *1 below.
-
-
- Intent i = new Intent().setPackage(c.alias.getPackageName());
- i.setAction(c.action);
- ComponentAliasMessage m;
-
- try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext, TAG)) {
- log("Sending broadcast: " + i);
- sContext.sendBroadcast(i);
-
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onReceive");
- assertThat(m.getSenderIdentity()).isEqualTo(c.target.flattenToShortString());
- assertThat(m.getIntent().getComponent()).isEqualTo(c.target);
-
- // *1 -- if the alias and target are in the same package, we expect one more
- // message.
- if (c.alias.getPackageName().equals(c.target.getPackageName())) {
- m = receiver.waitForNextMessage();
- assertThat(m.getMethodName()).isEqualTo("onReceive");
- assertThat(m.getSenderIdentity()).isEqualTo(c.target.flattenToShortString());
- assertThat(m.getIntent().getComponent()).isEqualTo(c.target);
- }
- receiver.ensureNoMoreMessages();
- }
- });
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java
deleted file mode 100644
index ee20379..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasEnableWithDeviceConfigTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-import android.os.Build;
-import android.provider.DeviceConfig;
-
-import com.android.compatibility.common.util.DeviceConfigStateHelper;
-import com.android.compatibility.common.util.ShellUtils;
-import com.android.compatibility.common.util.TestUtils;
-
-import org.junit.AfterClass;
-import org.junit.Assume;
-import org.junit.Test;
-
-public class ComponentAliasEnableWithDeviceConfigTest {
- protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
-
- @AfterClass
- public static void restoreDeviceConfig() throws Exception {
- sDeviceConfig.close();
- }
-
- @Test
- public void enableComponentAliasWithCompatFlag() throws Exception {
- Assume.assumeTrue(Build.isDebuggable());
-
- sDeviceConfig.set("component_alias_overrides", "");
-
- // First, disable with both compat-id and device config.
- ShellUtils.runShellCommand(
- "am compat disable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
- sDeviceConfig.set("enable_experimental_component_alias", "");
-
- TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
- return ShellUtils.runShellCommand("dumpsys activity component-alias")
- .indexOf("Enabled: false") > 0;
- });
-
- // Then, enable by device config.
- sDeviceConfig.set("enable_experimental_component_alias", "true");
-
- // Make sure the feature is actually enabled.
- TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
- return ShellUtils.runShellCommand("dumpsys activity component-alias")
- .indexOf("Enabled: true") > 0;
- });
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java
deleted file mode 100644
index d41696f..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.DataClass;
-
-/**
- * Parcelabe containing a "message" that's meant to be delivered via BroadcastMessenger.
- *
- * To add a new field, just add a private member field, and run:
- * codegen $ANDROID_BUILD_TOP/frameworks/base/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java
- */
-@DataClass(
- genConstructor = false,
- genSetters = true,
- genToString = true,
- genAidl = false)
-public final class ComponentAliasMessage implements Parcelable {
- public ComponentAliasMessage() {
- }
-
- @Nullable
- private String mMessage;
-
- @Nullable
- private String mMethodName;
-
- @Nullable
- private String mSenderIdentity;
-
- @Nullable
- private Intent mIntent;
-
- @Nullable
- private ComponentName mComponent;
-
-
-
- // Code below generated by codegen v1.0.23.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- @DataClass.Generated.Member
- public @Nullable String getMessage() {
- return mMessage;
- }
-
- @DataClass.Generated.Member
- public @Nullable String getMethodName() {
- return mMethodName;
- }
-
- @DataClass.Generated.Member
- public @Nullable String getSenderIdentity() {
- return mSenderIdentity;
- }
-
- @DataClass.Generated.Member
- public @Nullable Intent getIntent() {
- return mIntent;
- }
-
- @DataClass.Generated.Member
- public @Nullable ComponentName getComponent() {
- return mComponent;
- }
-
- @DataClass.Generated.Member
- public @NonNull ComponentAliasMessage setMessage(@NonNull String value) {
- mMessage = value;
- return this;
- }
-
- @DataClass.Generated.Member
- public @NonNull ComponentAliasMessage setMethodName(@NonNull String value) {
- mMethodName = value;
- return this;
- }
-
- @DataClass.Generated.Member
- public @NonNull ComponentAliasMessage setSenderIdentity(@NonNull String value) {
- mSenderIdentity = value;
- return this;
- }
-
- @DataClass.Generated.Member
- public @NonNull ComponentAliasMessage setIntent(@NonNull Intent value) {
- mIntent = value;
- return this;
- }
-
- @DataClass.Generated.Member
- public @NonNull ComponentAliasMessage setComponent(@NonNull ComponentName value) {
- mComponent = value;
- return this;
- }
-
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "ComponentAliasMessage { " +
- "message = " + mMessage + ", " +
- "methodName = " + mMethodName + ", " +
- "senderIdentity = " + mSenderIdentity + ", " +
- "intent = " + mIntent + ", " +
- "component = " + mComponent +
- " }";
- }
-
- @Override
- @DataClass.Generated.Member
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- // You can override field parcelling by defining methods like:
- // void parcelFieldName(Parcel dest, int flags) { ... }
-
- byte flg = 0;
- if (mMessage != null) flg |= 0x1;
- if (mMethodName != null) flg |= 0x2;
- if (mSenderIdentity != null) flg |= 0x4;
- if (mIntent != null) flg |= 0x8;
- if (mComponent != null) flg |= 0x10;
- dest.writeByte(flg);
- if (mMessage != null) dest.writeString(mMessage);
- if (mMethodName != null) dest.writeString(mMethodName);
- if (mSenderIdentity != null) dest.writeString(mSenderIdentity);
- if (mIntent != null) dest.writeTypedObject(mIntent, flags);
- if (mComponent != null) dest.writeTypedObject(mComponent, flags);
- }
-
- @Override
- @DataClass.Generated.Member
- public int describeContents() { return 0; }
-
- /** @hide */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @DataClass.Generated.Member
- /* package-private */ ComponentAliasMessage(@NonNull Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
-
- byte flg = in.readByte();
- String message = (flg & 0x1) == 0 ? null : in.readString();
- String methodName = (flg & 0x2) == 0 ? null : in.readString();
- String senderIdentity = (flg & 0x4) == 0 ? null : in.readString();
- Intent intent = (flg & 0x8) == 0 ? null : (Intent) in.readTypedObject(Intent.CREATOR);
- ComponentName component = (flg & 0x10) == 0 ? null : (ComponentName) in.readTypedObject(ComponentName.CREATOR);
-
- this.mMessage = message;
- this.mMethodName = methodName;
- this.mSenderIdentity = senderIdentity;
- this.mIntent = intent;
- this.mComponent = component;
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<ComponentAliasMessage> CREATOR
- = new Parcelable.Creator<ComponentAliasMessage>() {
- @Override
- public ComponentAliasMessage[] newArray(int size) {
- return new ComponentAliasMessage[size];
- }
-
- @Override
- public ComponentAliasMessage createFromParcel(@NonNull Parcel in) {
- return new ComponentAliasMessage(in);
- }
- };
-
- @DataClass.Generated(
- time = 1630098801203L,
- codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasMessage.java",
- inputSignatures = "private @android.annotation.Nullable java.lang.String mMessage\nprivate @android.annotation.Nullable java.lang.String mMethodName\nprivate @android.annotation.Nullable java.lang.String mSenderIdentity\nprivate @android.annotation.Nullable android.content.Intent mIntent\nprivate @android.annotation.Nullable android.content.ComponentName mComponent\nclass ComponentAliasMessage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true, genToString=true, genAidl=false)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java
deleted file mode 100644
index 0899886..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasNotSupportedOnUserBuildTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Build;
-import android.provider.DeviceConfig;
-
-import com.android.compatibility.common.util.DeviceConfigStateHelper;
-import com.android.compatibility.common.util.ShellUtils;
-
-import org.junit.AfterClass;
-import org.junit.Assume;
-import org.junit.Test;
-
-/**
- * Test to make sure component-alias can't be enabled on user builds.
- */
-public class ComponentAliasNotSupportedOnUserBuildTest {
- protected static final DeviceConfigStateHelper sDeviceConfig = new DeviceConfigStateHelper(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS);
-
- @AfterClass
- public static void restoreDeviceConfig() throws Exception {
- sDeviceConfig.close();
- }
-
- @Test
- public void enableComponentAliasWithCompatFlag() throws Exception {
- Assume.assumeFalse(Build.isDebuggable());
-
- // Try to enable it by both the device config and compat-id.
- sDeviceConfig.set("enable_experimental_component_alias", "true");
- ShellUtils.runShellCommand(
- "am compat enable --no-kill USE_EXPERIMENTAL_COMPONENT_ALIAS android");
-
- // Sleep for an arbitrary amount of time, so the config would sink in, if there was
- // no "not on user builds" check.
-
- Thread.sleep(5000);
-
- // Make sure the feature is still disabled.
- assertThat(ShellUtils.runShellCommand("dumpsys activity component-alias")
- .indexOf("Enabled: false") > 0).isTrue();
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasServiceTest.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasServiceTest.java
deleted file mode 100644
index f0ff088..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasServiceTest.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.componentalias.tests;
-
-import static android.content.Context.BIND_AUTO_CREATE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.MAIN_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.SUB1_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.SUB2_PACKAGE;
-import static android.content.componentalias.tests.ComponentAliasTestCommon.TAG;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.core.IsNot.not;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-
-import com.android.compatibility.common.util.BroadcastMessenger;
-import com.android.compatibility.common.util.BroadcastMessenger.Receiver;
-import com.android.compatibility.common.util.ShellUtils;
-import com.android.compatibility.common.util.TestUtils;
-
-import org.junit.Assume;
-import org.junit.Test;
-
-import java.util.function.Consumer;
-
-/**
- * Test for the experimental "Component alias" feature.
- *
- * Note this test exercises the relevant APIs, but don't actually check if the aliases are
- * resolved.
- *
- * Note all the helper APKs are battery-exempted (via AndroidTest.xml), so they can run
- * BG services.
- */
-public class ComponentAliasServiceTest extends BaseComponentAliasTest {
- /**
- * Service connection used throughout the tests. It sends a message for each callback via
- * the messenger.
- */
- private static final ServiceConnection sServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- log("onServiceConnected: " + name);
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity("sServiceConnection")
- .setMethodName("onServiceConnected")
- .setComponent(name);
-
- BroadcastMessenger.send(sContext, TAG, m);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- log("onServiceDisconnected: " + name);
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity("sServiceConnection")
- .setMethodName("onServiceDisconnected")
- .setComponent(name);
-
- BroadcastMessenger.send(sContext, TAG, m);
- }
-
- @Override
- public void onBindingDied(ComponentName name) {
- log("onBindingDied: " + name);
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity("sServiceConnection")
- .setMethodName("onBindingDied");
-
- BroadcastMessenger.send(sContext, TAG, m);
- }
-
- @Override
- public void onNullBinding(ComponentName name) {
- log("onNullBinding: " + name);
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity("sServiceConnection")
- .setMethodName("onNullBinding");
-
- BroadcastMessenger.send(sContext, TAG, m);
- }
- };
-
- private void testStartAndStopService_common(
- Intent originalIntent,
- ComponentName componentNameForClient,
- ComponentName componentNameForTarget) {
-
- ComponentAliasMessage m;
-
- try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext, TAG)) {
- // Start the service.
- ComponentName result = sContext.startService(originalIntent);
- assertThat(result).isEqualTo(componentNameForClient);
-
- // Check
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onStartCommand");
- // The app sees the rewritten intent.
- assertThat(m.getIntent().getComponent()).isEqualTo(componentNameForTarget);
-
- // Verify the original intent.
- assertThat(m.getIntent().getOriginalIntent().getComponent())
- .isEqualTo(originalIntent.getComponent());
- assertThat(m.getIntent().getOriginalIntent().getPackage())
- .isEqualTo(originalIntent.getPackage());
-
- // Stop the service.
- sContext.stopService(originalIntent);
-
- // Check
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onDestroy");
-
- receiver.ensureNoMoreMessages();
- }
- }
-
- private void forEachCombo(Consumer<Combo> callback) {
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias00"),
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Target00"),
- MAIN_PACKAGE + ".IS_ALIAS_00").apply(callback);
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias01"),
- new ComponentName(SUB1_PACKAGE, MAIN_PACKAGE + ".s.Target01"),
- MAIN_PACKAGE + ".IS_ALIAS_01").apply(callback);
- new Combo(
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias02"),
- new ComponentName(SUB2_PACKAGE, MAIN_PACKAGE + ".s.Target02"),
- MAIN_PACKAGE + ".IS_ALIAS_02").apply(callback);
- }
-
- @Test
- public void testStartAndStopService_explicitComponentName() {
- forEachCombo((c) -> {
- Intent i = new Intent().setComponent(c.alias);
- testStartAndStopService_common(i, c.alias, c.target);
- });
- }
-
- @Test
- public void testStartAndStopService_explicitPackageName() {
- forEachCombo((c) -> {
- Intent i = new Intent().setPackage(c.alias.getPackageName());
- i.setAction(c.action);
-
- testStartAndStopService_common(i, c.alias, c.target);
- });
- }
-
- @Test
- public void testStartAndStopService_override() throws Exception {
- Intent i = new Intent().setPackage(MAIN_PACKAGE);
- i.setAction(MAIN_PACKAGE + ".IS_ALIAS_01");
-
- // Change some of the aliases from what's defined in <meta-data>.
-
- ComponentName aliasA = new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias01");
- ComponentName targetA = new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Target02");
-
- ComponentName aliasB = new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias02");
- ComponentName targetB = new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Target01");
-
- sDeviceConfig.set("component_alias_overrides",
- aliasA.flattenToShortString() + ":" + targetA.flattenToShortString()
- + ","
- + aliasB.flattenToShortString() + ":" + targetB.flattenToShortString());
-
- TestUtils.waitUntil("Wait until component alias is actually enabled", () -> {
- return ShellUtils.runShellCommand("dumpsys activity component-alias")
- .indexOf(aliasA.flattenToShortString()
- + " -> " + targetA.flattenToShortString()) > 0;
- });
-
-
- testStartAndStopService_common(i, aliasA, targetA);
- }
-
- private void testBindAndUnbindService_common(
- Intent originalIntent,
- ComponentName componentNameForClient,
- ComponentName componentNameForTarget) {
- ComponentAliasMessage m;
-
- try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext, TAG)) {
- // Bind to the service.
- assertThat(sContext.bindService(
- originalIntent, sServiceConnection, BIND_AUTO_CREATE)).isTrue();
-
- // Check the target side behavior.
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onBind");
- // The app sees the rewritten intent.
- assertThat(m.getIntent().getComponent()).isEqualTo(componentNameForTarget);
-
- // Verify the original intent.
- assertThat(m.getIntent().getOriginalIntent().getComponent())
- .isEqualTo(originalIntent.getComponent());
- assertThat(m.getIntent().getOriginalIntent().getPackage())
- .isEqualTo(originalIntent.getPackage());
-
- // Check the client side behavior.
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onServiceConnected");
- // The app sees the rewritten intent.
- assertThat(m.getComponent()).isEqualTo(componentNameForClient);
-
- // Unbind.
- sContext.unbindService(sServiceConnection);
-
- // Check the target side behavior.
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onDestroy");
-
- // Note onServiceDisconnected() won't be called in this case.
- receiver.ensureNoMoreMessages();
- }
- }
-
- @Test
- public void testBindService_explicitComponentName() {
- forEachCombo((c) -> {
- Intent i = new Intent().setComponent(c.alias);
-
- testBindAndUnbindService_common(i, c.alias, c.target);
- });
-
- }
-
- @Test
- public void testBindService_explicitPackageName() {
- forEachCombo((c) -> {
- Intent i = new Intent().setPackage(c.alias.getPackageName());
- i.setAction(c.action);
-
- testBindAndUnbindService_common(i, c.alias, c.target);
- });
- }
-
- /**
- * Make sure, when the service process is killed, the client will get a callback with the
- * right component name.
- */
- @Test
- public void testBindService_serviceKilled() {
-
- // We need to kill SUB2_PACKAGE, don't run it for this package.
- Assume.assumeThat(sContext.getPackageName(), not(SUB2_PACKAGE));
-
- Intent originalIntent = new Intent().setPackage(MAIN_PACKAGE);
- originalIntent.setAction(MAIN_PACKAGE + ".IS_ALIAS_02");
-
- final ComponentName componentNameForClient =
- new ComponentName(MAIN_PACKAGE, MAIN_PACKAGE + ".s.Alias02");
- final ComponentName componentNameForTarget =
- new ComponentName(SUB2_PACKAGE, MAIN_PACKAGE + ".s.Target02");
-
- ComponentAliasMessage m;
-
- try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext, TAG)) {
- // Bind to the service.
- assertThat(sContext.bindService(
- originalIntent, sServiceConnection, BIND_AUTO_CREATE)).isTrue();
-
- // Check the target side behavior.
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onBind");
-
- m = receiver.waitForNextMessage();
- assertThat(m.getMethodName()).isEqualTo("onServiceConnected");
- assertThat(m.getComponent()).isEqualTo(componentNameForClient);
- // We don't need to check all the fields because these are tested else where.
-
- // Now kill the service process.
- ShellUtils.runShellCommand("su 0 killall %s", SUB2_PACKAGE);
-
- // Check the target side behavior.
- m = receiver.waitForNextMessage();
-
- assertThat(m.getMethodName()).isEqualTo("onServiceDisconnected");
- assertThat(m.getComponent()).isEqualTo(componentNameForClient);
-
- receiver.ensureNoMoreMessages();
- }
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasTestCommon.java b/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasTestCommon.java
deleted file mode 100644
index 165d728..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/ComponentAliasTestCommon.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests;
-
-public final class ComponentAliasTestCommon {
- private ComponentAliasTestCommon() {
- }
-
- public static final String TAG = "ComponentAliasTest";
-
- public static final String MAIN_PACKAGE = "android.content.componentalias.tests";
-
- public static final String SUB1_PACKAGE = "android.content.componentalias.tests.sub1";
- public static final String SUB2_PACKAGE = "android.content.componentalias.tests.sub2";
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/BaseReceiver.java b/tests/componentalias/src/android/content/componentalias/tests/b/BaseReceiver.java
deleted file mode 100644
index 1d05e72..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/b/BaseReceiver.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.b;
-
-import static android.content.componentalias.tests.ComponentAliasTestCommon.TAG;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.componentalias.tests.ComponentAliasMessage;
-import android.util.Log;
-
-import com.android.compatibility.common.util.BroadcastMessenger;
-
-public class BaseReceiver extends BroadcastReceiver {
- private String getMyIdentity(Context context) {
- return (new ComponentName(context.getPackageName(), this.getClass().getCanonicalName()))
- .flattenToShortString();
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.i(TAG, "onReceive: on " + getMyIdentity(context) + " intent=" + intent);
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity(getMyIdentity(context))
- .setMethodName("onReceive")
- .setIntent(intent);
- BroadcastMessenger.send(context, TAG, m);
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/Target00.java b/tests/componentalias/src/android/content/componentalias/tests/b/Target00.java
deleted file mode 100644
index 8fb4e91..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/b/Target00.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.b;
-
-import android.content.componentalias.tests.s.BaseService;
-
-public class Target00 extends BaseReceiver {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/Target02.java b/tests/componentalias/src/android/content/componentalias/tests/b/Target02.java
deleted file mode 100644
index df7579d..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/b/Target02.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.b;
-
-public class Target02 extends BaseReceiver {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/Target03.java b/tests/componentalias/src/android/content/componentalias/tests/b/Target03.java
deleted file mode 100644
index 5ae5521..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/b/Target03.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.b;
-
-public class Target03 extends BaseReceiver {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/b/Target04.java b/tests/componentalias/src/android/content/componentalias/tests/b/Target04.java
deleted file mode 100644
index f9b9886..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/b/Target04.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.b;
-
-public class Target04 extends BaseReceiver {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/BaseService.java b/tests/componentalias/src/android/content/componentalias/tests/s/BaseService.java
deleted file mode 100644
index 535d9b8..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/BaseService.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-import static android.content.componentalias.tests.ComponentAliasTestCommon.TAG;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.componentalias.tests.ComponentAliasMessage;
-import android.os.Binder;
-import android.os.IBinder;
-import android.util.Log;
-
-import com.android.compatibility.common.util.BroadcastMessenger;
-
-public class BaseService extends Service {
- private String getMyIdentity() {
- return (new ComponentName(this.getPackageName(), this.getClass().getCanonicalName()))
- .flattenToShortString();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.i(TAG, "onStartCommand: on " + getMyIdentity() + " intent=" + intent);
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity(getMyIdentity())
- .setMethodName("onStartCommand")
- .setIntent(intent);
- BroadcastMessenger.send(this, TAG, m);
-
- return START_NOT_STICKY;
- }
-
- @Override
- public void onDestroy() {
- Log.i(TAG, "onDestroy: on " + getMyIdentity());
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity(getMyIdentity())
- .setMethodName("onDestroy");
- BroadcastMessenger.send(this, TAG, m);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- Log.i(TAG, "onBind: on " + getMyIdentity() + " intent=" + intent);
-
- ComponentAliasMessage m = new ComponentAliasMessage()
- .setSenderIdentity(getMyIdentity())
- .setMethodName("onBind")
- .setIntent(intent);
- BroadcastMessenger.send(this, TAG, m);
-
- return new Binder();
- }
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/Target00.java b/tests/componentalias/src/android/content/componentalias/tests/s/Target00.java
deleted file mode 100644
index 64b91f5..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/Target00.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-public class Target00 extends BaseService {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/Target01.java b/tests/componentalias/src/android/content/componentalias/tests/s/Target01.java
deleted file mode 100644
index bd58999..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/Target01.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-public class Target01 extends BaseService {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/Target02.java b/tests/componentalias/src/android/content/componentalias/tests/s/Target02.java
deleted file mode 100644
index 0ddf818..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/Target02.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-public class Target02 extends BaseService {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/Target03.java b/tests/componentalias/src/android/content/componentalias/tests/s/Target03.java
deleted file mode 100644
index 0dbc050..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/Target03.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-public class Target03 extends BaseService {
-}
diff --git a/tests/componentalias/src/android/content/componentalias/tests/s/Target04.java b/tests/componentalias/src/android/content/componentalias/tests/s/Target04.java
deleted file mode 100644
index 0994258..0000000
--- a/tests/componentalias/src/android/content/componentalias/tests/s/Target04.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.componentalias.tests.s;
-
-public class Target04 extends BaseService {
-}
diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
index 7375c16..43f2122 100644
--- a/tools/lint/fix/Android.bp
+++ b/tools/lint/fix/Android.bp
@@ -23,9 +23,8 @@
python_binary_host {
name: "lint_fix",
- main: "lint_fix.py",
- srcs: ["lint_fix.py"],
- libs: ["soong_lint_fix"],
+ main: "soong_lint_fix.py",
+ srcs: ["soong_lint_fix.py"],
}
python_library_host {
diff --git a/tools/lint/fix/README.md b/tools/lint/fix/README.md
index 367d0bc..a5ac2be 100644
--- a/tools/lint/fix/README.md
+++ b/tools/lint/fix/README.md
@@ -5,9 +5,12 @@
## What is this?
It's a python script that runs the framework linter,
-and then copies modified files back into the source tree.\
+and then (optionally) copies modified files back into the source tree.\
Why python, you ask? Because python is cool ¯\_(ツ)_/¯.
+Incidentally, this exposes a much simpler way to run individual lint checks
+against individual modules, so it's useful beyond applying fixes.
+
## Why?
Lint is not allowed to modify source files directly via lint's `--apply-suggestions` flag.
@@ -17,30 +20,11 @@
## How do I run it?
**WARNING: You probably want to commit/stash any changes to your working tree before doing this...**
-From this directory, run `python lint_fix.py -h`.
-The script's help output explains things that are omitted here.
-
-Alternatively, there is a python binary target you can build to make this
-available anywhere in your tree:
```
+source build/envsetup.sh
+lunch cf_x86_64_phone-userdebug # or any lunch target
m lint_fix
lint_fix -h
```
-**Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
-
-Example: `lint_fix frameworks/base/services/core/services.core.unboosted UseEnforcePermissionAnnotation --dry-run`
-```shell
-(
-export ANDROID_LINT_CHECK=UseEnforcePermissionAnnotation;
-cd $ANDROID_BUILD_TOP;
-source build/envsetup.sh;
-rm out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint/lint-report.html;
-m out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint/lint-report.html;
-cd out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint;
-unzip suggested-fixes.zip -d suggested-fixes;
-cd suggested-fixes;
-find . -path ./out -prune -o -name '*.java' -print | xargs -n 1 sh -c 'cp $1 $ANDROID_BUILD_TOP/$1' --;
-rm -rf suggested-fixes
-)
-```
+The script's help output explains things that are omitted here.
diff --git a/tools/lint/fix/lint_fix.py b/tools/lint/fix/lint_fix.py
deleted file mode 100644
index 1c83f7b..0000000
--- a/tools/lint/fix/lint_fix.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2023 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.
-#
-# 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.
-
-from soong_lint_fix import SoongLintFix
-
-SoongLintFix().run()
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py
index 3308df6..cd4d778d 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -13,14 +13,21 @@
# limitations under the License.
import argparse
+import json
import os
+import shutil
import subprocess
import sys
+import zipfile
ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP")
+ANDROID_PRODUCT_OUT = os.environ.get("ANDROID_PRODUCT_OUT")
+PRODUCT_OUT = ANDROID_PRODUCT_OUT.removeprefix(f"{ANDROID_BUILD_TOP}/")
+
+SOONG_UI = "build/soong/soong_ui.bash"
PATH_PREFIX = "out/soong/.intermediates"
PATH_SUFFIX = "android_common/lint"
-FIX_DIR = "suggested-fixes"
+FIX_ZIP = "suggested-fixes.zip"
class SoongLintFix:
"""
@@ -28,14 +35,12 @@
apply lint fixes to the platform via the necessary
combination of soong and shell commands.
- It provides some basic hooks for experimental code
- to tweak the generation of the resulting shell script.
+ It breaks up these operations into a few "private" methods
+ that are intentionally exposed so experimental code can tweak behavior.
- By default, it will apply lint fixes using the intermediate `suggested-fixes`
- directory that soong creates during its invocation of lint.
-
- The default argument parser configures a number of command line arguments to
- facilitate running lint via soong.
+ The entry point, `run`, will apply lint fixes using the
+ intermediate `suggested-fixes` directory that soong creates during its
+ invocation of lint.
Basic usage:
```
@@ -45,99 +50,95 @@
```
"""
def __init__(self):
- self._commands = None
+ self._parser = _setup_parser()
self._args = None
+ self._kwargs = None
self._path = None
self._target = None
- self._parser = _setup_parser()
- def add_argument(self, *args, **kwargs):
- """
- If necessary, add arguments to the underlying argparse.ArgumentParser before running
- """
- self._parser.add_argument(*args, **kwargs)
-
-
- def run(self, add_setup_commands=None, override_fix_commands=None):
+ def run(self, additional_setup=None, custom_fix=None):
"""
Run the script
- :param add_setup_commands: OPTIONAL function to add additional setup commands
- passed the command line arguments, path, and build target
- must return a list of strings (the additional commands)
- :param override_fix_commands: OPTIONAL function to override the fix commands
- passed the command line arguments, path, and build target
- must return a list of strings (the fix commands)
"""
self._setup()
- if add_setup_commands:
- self._commands += add_setup_commands(self._args, self._path, self._target)
-
- self._add_lint_report_commands()
+ self._find_module()
+ self._lint()
if not self._args.no_fix:
- if override_fix_commands:
- self._commands += override_fix_commands(self._args, self._path, self._target)
- else:
- self._commands += [
- f"cd {self._path}",
- f"unzip {FIX_DIR}.zip -d {FIX_DIR}",
- f"cd {FIX_DIR}",
- # Find all the java files in the fix directory, excluding the ./out subdirectory,
- # and copy them back into the same path within the tree.
- f"find . -path ./out -prune -o -name '*.java' -print | xargs -n 1 sh -c 'cp $1 $ANDROID_BUILD_TOP/$1 || exit 255' --",
- f"rm -rf {FIX_DIR}"
- ]
+ self._fix()
-
- if self._args.dry_run:
- print(self._get_commands_str())
- else:
- self._execute()
-
+ if self._args.print:
+ self._print()
def _setup(self):
self._args = self._parser.parse_args()
- self._commands = []
- self._path = f"{PATH_PREFIX}/{self._args.build_path}/{PATH_SUFFIX}"
- self._target = f"{self._path}/lint-report.html"
-
- if not self._args.dry_run:
- self._commands += [f"export ANDROID_BUILD_TOP={ANDROID_BUILD_TOP}"]
-
+ env = os.environ.copy()
if self._args.check:
- self._commands += [f"export ANDROID_LINT_CHECK={self._args.check}"]
+ env["ANDROID_LINT_CHECK"] = self._args.check
+ if self._args.lint_module:
+ env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._args.lint_module
+
+ self._kwargs = {
+ "env": env,
+ "executable": "/bin/bash",
+ "shell": True,
+ }
+
+ os.chdir(ANDROID_BUILD_TOP)
- def _add_lint_report_commands(self):
- self._commands += [
- "cd $ANDROID_BUILD_TOP",
- "source build/envsetup.sh",
- # remove the file first so soong doesn't think there is no work to do
- f"rm {self._target}",
- # remove in case there are fixes from a prior run,
- # that we don't want applied if this run fails
- f"rm {self._path}/{FIX_DIR}.zip",
- f"m {self._target}",
- ]
+ def _find_module(self):
+ print("Refreshing soong modules...")
+ try:
+ os.mkdir(ANDROID_PRODUCT_OUT)
+ except OSError:
+ pass
+ subprocess.call(f"{SOONG_UI} --make-mode {PRODUCT_OUT}/module-info.json", **self._kwargs)
+ print("done.")
+
+ with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f:
+ module_info = json.load(f)
+
+ if self._args.module not in module_info:
+ sys.exit(f"Module {self._args.module} not found!")
+
+ module_path = module_info[self._args.module]["path"][0]
+ print(f"Found module {module_path}/{self._args.module}.")
+
+ self._path = f"{PATH_PREFIX}/{module_path}/{self._args.module}/{PATH_SUFFIX}"
+ self._target = f"{self._path}/lint-report.txt"
- def _get_commands_str(self):
- prefix = "(\n"
- delimiter = ";\n"
- suffix = "\n)"
- return f"{prefix}{delimiter.join(self._commands)}{suffix}"
+ def _lint(self):
+ print("Cleaning up any old lint results...")
+ try:
+ os.remove(f"{self._target}")
+ os.remove(f"{self._path}/{FIX_ZIP}")
+ except FileNotFoundError:
+ pass
+ print("done.")
+
+ print(f"Generating {self._target}")
+ subprocess.call(f"{SOONG_UI} --make-mode {self._target}", **self._kwargs)
+ print("done.")
- def _execute(self, with_echo=True):
- if with_echo:
- exec_commands = []
- for c in self._commands:
- exec_commands.append(f'echo "{c}"')
- exec_commands.append(c)
- self._commands = exec_commands
+ def _fix(self):
+ print("Copying suggested fixes to the tree...")
+ with zipfile.ZipFile(f"{self._path}/{FIX_ZIP}") as zip:
+ for name in zip.namelist():
+ if name.startswith("out") or not name.endswith(".java"):
+ continue
+ with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
+ shutil.copyfileobj(src, dst)
+ print("done.")
- subprocess.call(self._get_commands_str(), executable='/bin/bash', shell=True)
+
+ def _print(self):
+ print("### lint-report.txt ###", end="\n\n")
+ with open(self._target, "r") as f:
+ print(f.read())
def _setup_parser():
@@ -147,23 +148,26 @@
2. Run lint on the specified target.
3. Copy the modified files, from soong's intermediate directory, back into the tree.
- **Gotcha**: You must have run `source build/envsetup.sh` and `lunch`
- so that the `ANDROID_BUILD_TOP` environment variable has been set.
- Alternatively, set it manually in your shell.
+ **Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
""", formatter_class=argparse.RawTextHelpFormatter)
- parser.add_argument('build_path', metavar='build_path', type=str,
- help='The build module to run '
- '(e.g. frameworks/base/framework-minus-apex or '
- 'frameworks/base/services/core/services.core.unboosted)')
+ parser.add_argument('module',
+ help='The soong build module to run '
+ '(e.g. framework-minus-apex or services.core.unboosted)')
- parser.add_argument('--check', metavar='check', type=str,
+ parser.add_argument('--check',
help='Which lint to run. Passed to the ANDROID_LINT_CHECK environment variable.')
- parser.add_argument('--dry-run', dest='dry_run', action='store_true',
- help='Just print the resulting shell script instead of running it.')
+ parser.add_argument('--lint-module',
+ help='Specific lint module to run. Passed to the ANDROID_LINT_CHECK_EXTRA_MODULES environment variable.')
- parser.add_argument('--no-fix', dest='no_fix', action='store_true',
+ parser.add_argument('--no-fix', action='store_true',
help='Just build and run the lint, do NOT apply the fixes.')
+ parser.add_argument('--print', action='store_true',
+ help='Print the contents of the generated lint-report.txt at the end.')
+
return parser
+
+if __name__ == "__main__":
+ SoongLintFix().run()
\ No newline at end of file
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index b4f6a1c..935bade 100644
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -35,7 +35,8 @@
CallingIdentityTokenDetector.ISSUE_RESULT_OF_CLEAR_IDENTITY_CALL_NOT_STORED_IN_VARIABLE,
CallingSettingsNonUserGetterMethodsDetector.ISSUE_NON_USER_GETTER_CALLED,
SaferParcelChecker.ISSUE_UNSAFE_API_USAGE,
- PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS,
+ // TODO: Currently crashes due to OOM issue
+ // PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS,
PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE,
PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD,
)
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
index f7560a7..75b0073 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
@@ -321,6 +321,34 @@
)
}
+ fun testDoesDetectIssuesShortStringsNotAllowed() {
+ lint().files(java(
+ """
+ package test.pkg;
+ import android.annotation.EnforcePermission;
+ public class TestClass121 extends IFooMethod.Stub {
+ @Override
+ @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
+ public void testMethodAnyLiteral() {}
+ }
+ """).indented(),
+ *stubs
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass121.java:6: Error: The method \
+ TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) \
+ which differs from the overridden method Stub.testMethodAnyLiteral: \
+ @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \
+ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
+ public void testMethodAnyLiteral() {}
+ ~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """.addLineContinuation()
+ )
+ }
+
/* Stubs */
// A service with permission annotation on the method.